ryugi-artifacts 1.6.0 → 1.6.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 (146) hide show
  1. package/bin/ryugi-artifacts.cjs +53 -0
  2. package/dist/runtime/robots.txt +9 -0
  3. package/dist/server.cjs +66 -5
  4. package/dist/start-server.sh +279 -0
  5. package/dist/viewer/{CloudDocument-Cmt0f5LX.js → CloudDocument-Ba6KrnqA.js} +1 -1
  6. package/dist/viewer/{DocumentEditor-RfVa-8pR.js → DocumentEditor-BS16Wb_Z.js} +158 -158
  7. package/dist/viewer/{DocumentPage-Cg4Y7n8Z.js → DocumentPage-DQmrD0th.js} +1 -1
  8. package/dist/viewer/{abnfDiagram-VCTEODGH-Ch1PrcW_.js → abnfDiagram-VCTEODGH-DuJfhZTl.js} +1 -1
  9. package/dist/viewer/app-icon-6WJOuhLx.svg +1 -0
  10. package/dist/viewer/app-icon-Bm9-i4yr.png +0 -0
  11. package/dist/viewer/{ar-SA-G6X2FPQ2-BZLJnXPp.js → ar-SA-G6X2FPQ2-CVlRFGvR.js} +1 -1
  12. package/dist/viewer/{architectureDiagram-5GKGNRK7-Crf3vLUm.js → architectureDiagram-5GKGNRK7-Ca-sK1k9.js} +1 -1
  13. package/dist/viewer/{az-AZ-76LH7QW2-CJCCtBBF.js → az-AZ-76LH7QW2-CzO5U4tE.js} +1 -1
  14. package/dist/viewer/{bg-BG-XCXSNQG7-A9uZROfi.js → bg-BG-XCXSNQG7-DLheLFGn.js} +1 -1
  15. package/dist/viewer/{blockDiagram-I7D4REHJ-kmyfDg5y.js → blockDiagram-I7D4REHJ-CVWXNFVb.js} +1 -1
  16. package/dist/viewer/{bn-BD-2XOGV67Q-CMY785z7.js → bn-BD-2XOGV67Q-DvnFf2ym.js} +1 -1
  17. package/dist/viewer/{c4Diagram-7LVT6UL2-DtRUOCrL.js → c4Diagram-7LVT6UL2-CddHgiim.js} +1 -1
  18. package/dist/viewer/{ca-ES-6MX7JW3Y-BYYBxQ2h.js → ca-ES-6MX7JW3Y-1SQM_Wxy.js} +1 -1
  19. package/dist/viewer/{chunk-4HAMMTFA-D7lBPl2E.js → chunk-4HAMMTFA-B7k7y3et.js} +1 -1
  20. package/dist/viewer/{chunk-EIO257PC-BvW_EZuD.js → chunk-EIO257PC-CNxgWaGL.js} +1 -1
  21. package/dist/viewer/{chunk-GMAD6QVW-B0KZ3k-s.js → chunk-GMAD6QVW-Do0Tih79.js} +1 -1
  22. package/dist/viewer/{chunk-GVQU2GXP-vAqsTjwW.js → chunk-GVQU2GXP-C9mWLYpa.js} +1 -1
  23. package/dist/viewer/{chunk-IMKFNOWR-CVmDn72x.js → chunk-IMKFNOWR-BqsuylOZ.js} +1 -1
  24. package/dist/viewer/{chunk-L3NEJ4N5-DhAe4WGx.js → chunk-L3NEJ4N5-D_AVAMEp.js} +1 -1
  25. package/dist/viewer/{chunk-OSK3NFVY-CD-0X77m.js → chunk-OSK3NFVY-BKczRUt9.js} +1 -1
  26. package/dist/viewer/{chunk-PWAF6VOD-Cku_5L2L.js → chunk-PWAF6VOD-CcIRMiiP.js} +1 -1
  27. package/dist/viewer/{chunk-SHT3W25Y-DhRf-pGm.js → chunk-SHT3W25Y-D8R29R_u.js} +1 -1
  28. package/dist/viewer/{chunk-SVP7TREG-DmQ8yYT7.js → chunk-SVP7TREG-DvPbOdMe.js} +1 -1
  29. package/dist/viewer/{chunk-TICWLB2K-ptqkK9g5.js → chunk-TICWLB2K-v1pSr6BB.js} +1 -1
  30. package/dist/viewer/{classDiagram-ZZMXUADV-D5iY4ZXd.js → classDiagram-ZZMXUADV-BJqflR68.js} +1 -1
  31. package/dist/viewer/{classDiagram-v2-VYDZK3BY-D5iY4ZXd.js → classDiagram-v2-VYDZK3BY-BJqflR68.js} +1 -1
  32. package/dist/viewer/{cs-CZ-2BRQDIVT-Dzf23tSv.js → cs-CZ-2BRQDIVT-CuIWOyM9.js} +1 -1
  33. package/dist/viewer/{cynefinDiagram-5FMLGOSQ-CPkt5HTK.js → cynefinDiagram-5FMLGOSQ-CarHaJWA.js} +1 -1
  34. package/dist/viewer/{da-DK-5WZEPLOC-kk5u8oeh.js → da-DK-5WZEPLOC-BNpk9O4Z.js} +1 -1
  35. package/dist/viewer/{dagre-GXQ25YYZ-Bhb-6j9p.js → dagre-GXQ25YYZ-jKxlutMc.js} +1 -1
  36. package/dist/viewer/{de-DE-XR44H4JA-SMlX6klW.js → de-DE-XR44H4JA-DeRYYEYN.js} +1 -1
  37. package/dist/viewer/{diagram-S7CK7UJ4-CvFeOngn.js → diagram-S7CK7UJ4-BzGz76pK.js} +1 -1
  38. package/dist/viewer/{diagram-UQ7AKVKN-YhpPzvtc.js → diagram-UQ7AKVKN-DDsoAc73.js} +1 -1
  39. package/dist/viewer/{diagram-VX7I27RA-CHXupSCr.js → diagram-VX7I27RA-BIeolo3r.js} +1 -1
  40. package/dist/viewer/{diagram-Z3DM3KII-Q_9dAatE.js → diagram-Z3DM3KII-CU7mw2ow.js} +1 -1
  41. package/dist/viewer/{dist-KarY-eub.js → dist-AH0bdIVa.js} +1 -1
  42. package/dist/viewer/{dist-CpeuWhgo.js → dist-BSeJYKLj.js} +1 -1
  43. package/dist/viewer/{dist-D54iKVBK.js → dist-BbW5iWCe.js} +1 -1
  44. package/dist/viewer/{dist-DPsEN2aY.js → dist-BeULvDu_.js} +1 -1
  45. package/dist/viewer/{dist-BuhqQu7t.js → dist-BgSBKOA3.js} +1 -1
  46. package/dist/viewer/{dist-HBBjtVCs.js → dist-BlXyXxst.js} +1 -1
  47. package/dist/viewer/{dist-BUQddJyY.js → dist-BppD0RS2.js} +1 -1
  48. package/dist/viewer/{dist-B9l6xPFH.js → dist-Bu_voPaa.js} +1 -1
  49. package/dist/viewer/{dist-B5smEokn.js → dist-C-ieEyE1.js} +1 -1
  50. package/dist/viewer/{dist-CQLwSz5A.js → dist-C21gJBBO.js} +1 -1
  51. package/dist/viewer/{dist-HEpf722E.js → dist-CHLFapPp.js} +1 -1
  52. package/dist/viewer/{dist-Cyyn2QnM.js → dist-CZsxPTNE.js} +1 -1
  53. package/dist/viewer/{dist-DuN7MgQk.js → dist-Cackv1h9.js} +1 -1
  54. package/dist/viewer/{dist-nBKLr6IT.js → dist-CbHHxvP1.js} +1 -1
  55. package/dist/viewer/{dist-B9MlS-yc.js → dist-CddCPamz.js} +1 -1
  56. package/dist/viewer/{dist-BiSGJruV.js → dist-CgYgXYmt.js} +1 -1
  57. package/dist/viewer/{dist-B9dFSb2w.js → dist-CitzQ6z1.js} +4 -4
  58. package/dist/viewer/{dist-rV_cA3xa.js → dist-Cu6PLla0.js} +1 -1
  59. package/dist/viewer/{dist-BYFhByvm.js → dist-CvB831yK.js} +1 -1
  60. package/dist/viewer/{dist-Caiv-ahd.js → dist-DA8TW41P.js} +1 -1
  61. package/dist/viewer/{dist-DUsSVxcw.js → dist-DC1HltnF.js} +1 -1
  62. package/dist/viewer/{dist-paIVcwaQ.js → dist-DX3SNcdm.js} +1 -1
  63. package/dist/viewer/{dist-f0EzsI-T.js → dist-D_Vtqh_s.js} +1 -1
  64. package/dist/viewer/{dist-DCGRsZVI.js → dist-DqbHnPRI.js} +1 -1
  65. package/dist/viewer/{ebnfDiagram-PWID7BFC-Hv9B-3hk.js → ebnfDiagram-PWID7BFC-BUmzlASS.js} +1 -1
  66. package/dist/viewer/{el-GR-BZB4AONW-DaH9owXi.js → el-GR-BZB4AONW-CU9I6jx_.js} +1 -1
  67. package/dist/viewer/{en-B4ZKOASM-YnGAFBsU.js → en-B4ZKOASM-DGboqHSv.js} +1 -1
  68. package/dist/viewer/{erDiagram-RLTQ6QDP-BTUs0BT2.js → erDiagram-RLTQ6QDP-DRUmIoEG.js} +1 -1
  69. package/dist/viewer/{es-ES-U4NZUMDT-BuoQIO3M.js → es-ES-U4NZUMDT-j5HevUjd.js} +1 -1
  70. package/dist/viewer/{eu-ES-A7QVB2H4-DUhHVlZe.js → eu-ES-A7QVB2H4-FpISoaoc.js} +1 -1
  71. package/dist/viewer/{fa-IR-HGAKTJCU-CjJKc0am.js → fa-IR-HGAKTJCU-COJsQztN.js} +1 -1
  72. package/dist/viewer/{fi-FI-Z5N7JZ37-CMFLRD0_.js → fi-FI-Z5N7JZ37-BNHsLnGq.js} +1 -1
  73. package/dist/viewer/flowDiagram-HODETNUW-BIce5Xbz.js +1 -0
  74. package/dist/viewer/{fr-FR-RHASNOE6-BHoSntIq.js → fr-FR-RHASNOE6-CM9a28Dh.js} +1 -1
  75. package/dist/viewer/{ganttDiagram-EL5Y4UJY-CeEQLTco.js → ganttDiagram-EL5Y4UJY-BVcwKFHE.js} +1 -1
  76. package/dist/viewer/{gl-ES-HMX3MZ6V-DICoY99I.js → gl-ES-HMX3MZ6V-C5aDlPBE.js} +1 -1
  77. package/dist/viewer/{he-IL-6SHJWFNN-CEe7bLWa.js → he-IL-6SHJWFNN-eFs-GSWn.js} +1 -1
  78. package/dist/viewer/{hi-IN-IWLTKZ5I-Dh_vRgBn.js → hi-IN-IWLTKZ5I-O1MAguUp.js} +1 -1
  79. package/dist/viewer/{hu-HU-A5ZG7DT2-Bidop9I6.js → hu-HU-A5ZG7DT2-B3meydQb.js} +1 -1
  80. package/dist/viewer/{id-ID-SAP4L64H-D183pYjJ.js → id-ID-SAP4L64H-PHNH2hzW.js} +1 -1
  81. package/dist/viewer/{image-GAAHSSAO-DGMqto4h.js → image-GAAHSSAO-BJifdIGE.js} +1 -1
  82. package/dist/viewer/index.html +21 -2
  83. package/dist/viewer/index.js +11 -11
  84. package/dist/viewer/index2.css +1 -33
  85. package/dist/viewer/{infoDiagram-27XIBGKW-BWBppJ8S.js → infoDiagram-27XIBGKW-D5Ag03ug.js} +1 -1
  86. package/dist/viewer/{ishikawaDiagram-5VMMS53U-DwcqlxrU.js → ishikawaDiagram-5VMMS53U-B9SCwzFe.js} +1 -1
  87. package/dist/viewer/{it-IT-JPQ66NNP-BmsXfM8K.js → it-IT-JPQ66NNP-DHOLiY7r.js} +1 -1
  88. package/dist/viewer/{ja-JP-DBVTYXUO-DyW8qb-0.js → ja-JP-DBVTYXUO-DTOuZQy0.js} +1 -1
  89. package/dist/viewer/{journeyDiagram-3NMN7TZE-DcgpwdKu.js → journeyDiagram-3NMN7TZE-CQvvWgCk.js} +1 -1
  90. package/dist/viewer/{kaa-6HZHGXH3-DJYup-gx.js → kaa-6HZHGXH3-1d0tKthK.js} +1 -1
  91. package/dist/viewer/{kab-KAB-ZGHBKWFO-D1TTkU3Z.js → kab-KAB-ZGHBKWFO-BaPyqYzR.js} +1 -1
  92. package/dist/viewer/{kanban-definition-UXKFOSKX-DY7wxWTD.js → kanban-definition-UXKFOSKX-Bg-Q4j28.js} +1 -1
  93. package/dist/viewer/{kk-KZ-P5N5QNE5-Bi6KJaJ_.js → kk-KZ-P5N5QNE5-BqF9n_h-.js} +1 -1
  94. package/dist/viewer/{km-KH-HSX4SM5Z-DUgQIxqu.js → km-KH-HSX4SM5Z-DPTb_KDC.js} +1 -1
  95. package/dist/viewer/{ko-KR-MTYHY66A-DBjXJgtG.js → ko-KR-MTYHY66A-DxGidADD.js} +1 -1
  96. package/dist/viewer/{ku-TR-6OUDTVRD-DZ7-3E8v.js → ku-TR-6OUDTVRD-BECmOCof.js} +1 -1
  97. package/dist/viewer/{lt-LT-XHIRWOB4-CZq0sHVB.js → lt-LT-XHIRWOB4-DKQm4SS0.js} +1 -1
  98. package/dist/viewer/{lv-LV-5QDEKY6T-CSnpouGk.js → lv-LV-5QDEKY6T-C4kUM3XE.js} +1 -1
  99. package/dist/viewer/{mindmap-definition-YA3MSWOX-B8Pb-wf1.js → mindmap-definition-YA3MSWOX-DRQfDlAQ.js} +1 -1
  100. package/dist/viewer/{mr-IN-CRQNXWMA-COt7YzBU.js → mr-IN-CRQNXWMA-CutHorlk.js} +1 -1
  101. package/dist/viewer/{my-MM-5M5IBNSE-D0Y1Da5n.js → my-MM-5M5IBNSE-BqscH03z.js} +1 -1
  102. package/dist/viewer/{nb-NO-T6EIAALU-oWyfOUMc.js → nb-NO-T6EIAALU-Dqflwtt9.js} +1 -1
  103. package/dist/viewer/{nl-NL-IS3SIHDZ-DmHiL8bF.js → nl-NL-IS3SIHDZ-BFq09PQX.js} +1 -1
  104. package/dist/viewer/{nn-NO-6E72VCQL-aPmsjnhV.js → nn-NO-6E72VCQL-BNIuUKOs.js} +1 -1
  105. package/dist/viewer/{oc-FR-POXYY2M6-IX-_Z2L9.js → oc-FR-POXYY2M6-Bz0jVYcW.js} +1 -1
  106. package/dist/viewer/{pa-IN-N4M65BXN-Bs_eqV6D.js → pa-IN-N4M65BXN-Diu6ZQtk.js} +1 -1
  107. package/dist/viewer/{pegDiagram-XKGWAZYB-CUKB72zB.js → pegDiagram-XKGWAZYB-COMSnXOr.js} +1 -1
  108. package/dist/viewer/percentages-BXMCSKIN-C4UC-sd0.js +1 -0
  109. package/dist/viewer/{pieDiagram-E7YTZNPT-PGM-bC7i.js → pieDiagram-E7YTZNPT-gHe-bm7N.js} +1 -1
  110. package/dist/viewer/{pl-PL-T2D74RX3-B62vM7Wd.js → pl-PL-T2D74RX3-CCwgP0Tt.js} +1 -1
  111. package/dist/viewer/{prod-CXChZPSF.js → prod-iZwju1YX.js} +12 -12
  112. package/dist/viewer/{pt-BR-5N22H2LF-DeO8w0-j.js → pt-BR-5N22H2LF-CNn18ypM.js} +1 -1
  113. package/dist/viewer/{pt-PT-UZXXM6DQ-DHRKu_nC.js → pt-PT-UZXXM6DQ-BMoRZ8jH.js} +1 -1
  114. package/dist/viewer/{quadrantDiagram-AXDQQJYC-BHGqqzJO.js → quadrantDiagram-AXDQQJYC-YkFWTX48.js} +1 -1
  115. package/dist/viewer/{railroadDiagram-O6MQD6OU-xkx7KBZh.js → railroadDiagram-O6MQD6OU-BP58ggYs.js} +1 -1
  116. package/dist/viewer/{requirementDiagram-BXWQKSXE-YoHOz35u.js → requirementDiagram-BXWQKSXE-B4RcZ6Uz.js} +1 -1
  117. package/dist/viewer/{ro-RO-JPDTUUEW-CZ7CkjNI.js → ro-RO-JPDTUUEW-SoalcNvO.js} +1 -1
  118. package/dist/viewer/robots.txt +9 -0
  119. package/dist/viewer/{ru-RU-B4JR7IUQ-sQ2YRlyV.js → ru-RU-B4JR7IUQ-DkWHaRhg.js} +1 -1
  120. package/dist/viewer/{sequenceDiagram-WJ2MYXX4-DdADoY-J.js → sequenceDiagram-WJ2MYXX4-C5uL0tpK.js} +1 -1
  121. package/dist/viewer/{si-LK-N5RQ5JYF-DLuQj109.js → si-LK-N5RQ5JYF-eD68JhLY.js} +1 -1
  122. package/dist/viewer/{sk-SK-C5VTKIMK-CMe_YVPU.js → sk-SK-C5VTKIMK-EXqkY3Ta.js} +1 -1
  123. package/dist/viewer/{sl-SI-NN7IZMDC-BPakRJTF.js → sl-SI-NN7IZMDC-D2V_J_sw.js} +1 -1
  124. package/dist/viewer/{stateDiagram-D77RDMKH-DDcsZcrC.js → stateDiagram-D77RDMKH-DkyLdU7q.js} +1 -1
  125. package/dist/viewer/{stateDiagram-v2-MP3YSRHH-BEL5Pgsi.js → stateDiagram-v2-MP3YSRHH-BMCqlN4T.js} +1 -1
  126. package/dist/viewer/subset-shared.chunk-pCVh-jxe.js +1 -0
  127. package/dist/viewer/{subset-worker.chunk-CAdHeyaa.js → subset-worker.chunk-B92dIZyQ.js} +1 -1
  128. package/dist/viewer/{sv-SE-XGPEYMSR-qERuvZ6s.js → sv-SE-XGPEYMSR-Bzbzaslo.js} +1 -1
  129. package/dist/viewer/{swimlanes-42K2YHIH-C1_2L18N.js → swimlanes-42K2YHIH-BWEGkPBm.js} +1 -1
  130. package/dist/viewer/{swimlanesDiagram-VR7AAH4N-ZxKOyUwv.js → swimlanesDiagram-VR7AAH4N-a8X5vJTG.js} +1 -1
  131. package/dist/viewer/{ta-IN-2NMHFXQM-CtrwjuD9.js → ta-IN-2NMHFXQM-BkRw8Ab-.js} +1 -1
  132. package/dist/viewer/{th-TH-HPSO5L25-D2ykN4P-.js → th-TH-HPSO5L25-DpxjfRSg.js} +1 -1
  133. package/dist/viewer/{timeline-definition-24CTP7MA-Bw3z4a18.js → timeline-definition-24CTP7MA-BEYELt88.js} +1 -1
  134. package/dist/viewer/{tr-TR-DEFEU3FU-DG1l6URL.js → tr-TR-DEFEU3FU-CDIHZRzE.js} +1 -1
  135. package/dist/viewer/{uk-UA-QMV73CPH-BOWgVI7Y.js → uk-UA-QMV73CPH-BX8bS5mk.js} +1 -1
  136. package/dist/viewer/{vennDiagram-4TSXK5OY-ba8MnyJG.js → vennDiagram-4TSXK5OY-CWnDIkB0.js} +1 -1
  137. package/dist/viewer/{vi-VN-M7AON7JQ-uVRFZJH3.js → vi-VN-M7AON7JQ-uPTH0PFh.js} +1 -1
  138. package/dist/viewer/{wardleyDiagram-VM6X3IG4-BXqHV7Of.js → wardleyDiagram-VM6X3IG4-DazKGA6Y.js} +1 -1
  139. package/dist/viewer/{xychartDiagram-S5SC5T6Z-DDAwmSA_.js → xychartDiagram-S5SC5T6Z-sQuCm3yV.js} +1 -1
  140. package/dist/viewer/{zh-CN-LNUGB5OW-CG6LZlkW.js → zh-CN-LNUGB5OW-CSw936pf.js} +1 -1
  141. package/dist/viewer/{zh-HK-E62DVLB3-B1k0qvGq.js → zh-HK-E62DVLB3-D5pp2ILq.js} +1 -1
  142. package/dist/viewer/{zh-TW-RAJ6MFWO-DnRoij4Q.js → zh-TW-RAJ6MFWO-DUVdEREg.js} +1 -1
  143. package/package.json +7 -2
  144. package/dist/viewer/flowDiagram-HODETNUW-CNs3HB63.js +0 -1
  145. package/dist/viewer/percentages-BXMCSKIN-B0uUmwNv.js +0 -1
  146. package/dist/viewer/subset-shared.chunk-CT_Q-SQa.js +0 -1
@@ -0,0 +1,53 @@
1
+ #!/usr/bin/env node
2
+ const { execFile, spawn } = require('node:child_process');
3
+ const fs = require('node:fs');
4
+ const path = require('node:path');
5
+ const readline = require('node:readline');
6
+ const { parseArgs } = require('node:util');
7
+
8
+ try {
9
+ const { values, positionals } = parseArgs({
10
+ options: {
11
+ help: { type: 'boolean', short: 'h' },
12
+ 'no-open': { type: 'boolean' },
13
+ 'project-dir': { type: 'string' },
14
+ },
15
+ allowPositionals: true,
16
+ });
17
+ if (values.help) {
18
+ console.log('Usage: ryugi-artifacts [project-directory] [--no-open]\n\nOpen the current project’s artifacts in your browser.\n\n --project-dir <path> Project directory (default: current directory)\n --no-open Print the URL without opening a browser\n -h, --help Show this help\n\nRequires Node.js and Bash (Git Bash on Windows).');
19
+ } else {
20
+ if (positionals.length > 1 || (positionals.length && values['project-dir'])) throw new Error('Specify one project directory.');
21
+ const project = fs.realpathSync(path.resolve(values['project-dir'] || positionals[0] || process.cwd()));
22
+ if (!fs.statSync(project).isDirectory()) throw new Error('Project path must be a directory.');
23
+ const child = spawn('bash', [path.join(__dirname, '../dist/start-server.sh'), '--project-dir', project, '--foreground', '--no-open'], {
24
+ stdio: ['inherit', 'pipe', 'inherit'],
25
+ });
26
+ let interrupted = false;
27
+ for (const signal of ['SIGINT', 'SIGTERM']) process.on(signal, () => {
28
+ interrupted = true;
29
+ child.kill('SIGTERM');
30
+ });
31
+ child.on('error', (error) => {
32
+ console.error(`Could not start artifacts: ${error.message}. Bash is required (Git Bash on Windows).`);
33
+ process.exitCode = 1;
34
+ });
35
+ readline.createInterface({ input: child.stdout }).on('line', (line) => {
36
+ let info;
37
+ try { info = JSON.parse(line); } catch { console.error(line); return; }
38
+ if (info.error) console.error(info.error);
39
+ if (info.type !== 'server-started') return;
40
+ console.log(info.url);
41
+ if (!info.reused) console.log('Press Ctrl+C to stop the server.');
42
+ if (values['no-open']) return;
43
+ const platform = process.platform;
44
+ const command = platform === 'darwin' ? 'open' : platform === 'win32' ? 'cmd' : 'xdg-open';
45
+ const args = platform === 'win32' ? ['/c', 'start', '""', info.url] : [info.url];
46
+ execFile(command, args, () => {});
47
+ });
48
+ child.on('close', (code) => { process.exitCode = interrupted ? 0 : code ?? 1; });
49
+ }
50
+ } catch (error) {
51
+ console.error(error.message);
52
+ process.exitCode = 1;
53
+ }
@@ -0,0 +1,9 @@
1
+ # Link previews may read shared pages; search and other crawlers may not.
2
+ User-agent: Twitterbot
3
+ User-agent: facebookexternalhit
4
+ User-agent: Slackbot-LinkExpanding
5
+ User-agent: Slack-ImgProxy
6
+ Allow: /
7
+
8
+ User-agent: *
9
+ Disallow: /
package/dist/server.cjs CHANGED
@@ -84850,6 +84850,8 @@ function callbackPage(result) {
84850
84850
  <meta charset="utf-8">
84851
84851
  <meta name="viewport" content="width=device-width, initial-scale=1">
84852
84852
  <meta name="referrer" content="no-referrer">
84853
+ <meta name="robots" content="noindex, nofollow">
84854
+ <meta name="description" content="Ryugi Cloud \u672C\u5730\u767B\u5F55\u7ED3\u679C\u3002\u5B8C\u6210\u8FDE\u63A5\u540E\uFF0C\u8FD4\u56DE Ryugi \u7EE7\u7EED\u53D1\u5E03\u548C\u5206\u4EAB Artifact\u3002">
84853
84855
  <title>${title}</title>
84854
84856
  <style>${STYLE2}</style>
84855
84857
  </head>
@@ -85187,6 +85189,25 @@ function createCloudRoutes(options) {
85187
85189
  };
85188
85190
  }
85189
85191
 
85192
+ // src/server/viewer-page.ts
85193
+ var escapeHtml2 = (value) => value.replace(/[&<>"']/g, (ch) => ({ "&": "&amp;", "<": "&lt;", ">": "&gt;", '"': "&quot;", "'": "&#39;" })[ch]);
85194
+ function viewerPage(template, page) {
85195
+ const values = {
85196
+ robots: "noindex, nofollow",
85197
+ description: page.description,
85198
+ "og:title": page.title,
85199
+ "og:description": page.description,
85200
+ "twitter:title": page.title,
85201
+ "twitter:description": page.description
85202
+ };
85203
+ return template.replace(/<title\b[^>]*>[\s\S]*?<\/title>/i, () => `<title>${escapeHtml2(page.title)}</title>`).replace(/(<meta\b[^>]*\b(?:name|property)="([^"]+)"[^>]*\bcontent=")([^"]*)("[^>]*>)/gi, (tag, prefix, name, value, suffix) => {
85204
+ const content = values[name] ?? (name === "og:image" || name === "twitter:image" ? new URL(value, page.url).href : void 0);
85205
+ return content === void 0 ? tag : `${prefix}${escapeHtml2(content)}${suffix}`;
85206
+ }).replace(/<\/head>/i, () => `<link rel="canonical" href="${escapeHtml2(page.url)}">
85207
+ <meta property="og:url" content="${escapeHtml2(page.url)}">
85208
+ </head>`);
85209
+ }
85210
+
85190
85211
  // src/server/watch.ts
85191
85212
  var import_node_fs14 = __toESM(require("node:fs"), 1);
85192
85213
  var import_node_path14 = __toESM(require("node:path"), 1);
@@ -85362,6 +85383,8 @@ var CONTENT_CSP = {
85362
85383
  };
85363
85384
  var SHELL_ROUTE = new RegExp(`^/(?:(${ARTIFACT_TYPES.join("|")})/([^/]+)/?)?$`);
85364
85385
  var API_ARTIFACT_ROUTE = /^\/api\/artifacts\/([^/]+)\/([^/]+)$/;
85386
+ var PREVIEW_ROUTE = /^\/preview\/(artboard|document|html)\/([a-z0-9][a-z0-9-]*)\/?$/;
85387
+ var API_PREVIEW_ROUTE = /^\/api\/preview\/([^/]+)\/([^/]+)$/;
85365
85388
  var API_DOCUMENT_ROUTE = /^\/api\/document\/([^/]+)\/(state|update|comments)$/;
85366
85389
  var MAX_COMMENT_OP = 64 * 1024;
85367
85390
  var MAX_DOCUMENT_UPDATE = 8 * 1024 * 1024;
@@ -85578,9 +85601,10 @@ async function startArtifactsServer(options) {
85578
85601
  const summaries = artifacts.map((entry) => ({
85579
85602
  type: entry.type,
85580
85603
  id: entry.id,
85581
- title: titleOf(readArtifact(entry.dir, entry), entry)
85604
+ title: titleOf(readArtifact(entry.dir, entry), entry),
85605
+ updatedAt: latestMtime(entry.dir)
85582
85606
  }));
85583
- sendJson(res, 200, { artifacts: summaries, warnings });
85607
+ sendJson(res, 200, { project: import_node_path15.default.basename(import_node_path15.default.dirname(import_node_path15.default.dirname(root))), artifacts: summaries, warnings });
85584
85608
  };
85585
85609
  function onClientText(text) {
85586
85610
  let message;
@@ -85626,6 +85650,7 @@ async function startArtifactsServer(options) {
85626
85650
  }
85627
85651
  const handleRequest = (req, res) => {
85628
85652
  touch();
85653
+ res.setHeader("X-Robots-Tag", "noindex, nofollow");
85629
85654
  const url2 = new URL(req.url ?? "/", "http://artifacts.local");
85630
85655
  let pathname;
85631
85656
  try {
@@ -85634,6 +85659,10 @@ async function startArtifactsServer(options) {
85634
85659
  send(res, 400, "Bad request");
85635
85660
  return;
85636
85661
  }
85662
+ if (pathname === "/robots.txt") {
85663
+ sendFile(res, import_node_path15.default.join(viewerDir, "robots.txt"));
85664
+ return;
85665
+ }
85637
85666
  if (pathname.startsWith("/c/")) {
85638
85667
  if (!pathname.startsWith(contentPrefix)) send(res, 404, "Not found");
85639
85668
  else serveContent(res, pathname.slice(contentPrefix.length));
@@ -85654,6 +85683,24 @@ async function startArtifactsServer(options) {
85654
85683
  serveList(res);
85655
85684
  return;
85656
85685
  }
85686
+ const previewMatch = API_PREVIEW_ROUTE.exec(pathname);
85687
+ if (previewMatch) {
85688
+ const [, type = "", id2 = ""] = previewMatch;
85689
+ const dir = resolveArtifactDir(root, type, id2);
85690
+ const ref = artifactKeyOf(`${type}/${id2}`);
85691
+ if (!dir || !ref) {
85692
+ sendJson(res, 404, { error: "Artifact not found" });
85693
+ return;
85694
+ }
85695
+ try {
85696
+ const payload = readArtifact(dir, ref);
85697
+ const title = titleOf(payload, ref);
85698
+ sendJson(res, 200, { ...publishPayload(ref, dir, title, payload), title, warnings: payload.warnings, contentBase: `${contentPrefix}${type}/${id2}/` });
85699
+ } catch {
85700
+ sendJson(res, 422, { error: "Preview unavailable" });
85701
+ }
85702
+ return;
85703
+ }
85657
85704
  const cloudMatch = cloud?.match(pathname);
85658
85705
  if (cloud && cloudMatch) {
85659
85706
  if (req.method !== "GET" && !(key2 !== null && safeEqual(key2, token)) && !sameOrigin(req)) {
@@ -85675,10 +85722,19 @@ async function startArtifactsServer(options) {
85675
85722
  serveArtifactApi(res, apiMatch[1], apiMatch[2]);
85676
85723
  return;
85677
85724
  }
85678
- if (SHELL_ROUTE.test(pathname) || pathname === "/index.html") {
85679
- const headers = { "Content-Security-Policy": VIEWER_CSP };
85725
+ if (SHELL_ROUTE.test(pathname) || PREVIEW_ROUTE.test(pathname) || pathname === "/index.html") {
85726
+ const ref = artifactKeyOf(pathname.replace(/^\/(?:preview\/)?/, "").replace(/\/$/, ""));
85727
+ const dir = ref && resolveArtifactDir(root, ref.type, ref.id);
85728
+ const project = import_node_path15.default.basename(import_node_path15.default.dirname(import_node_path15.default.dirname(root)));
85729
+ const title = ref ? dir ? titleOf(readArtifact(dir, ref), ref) : ref.id : `${project} \xB7 Artifacts`;
85730
+ const description = ref ? `\u5728 ${project} \u9879\u76EE\u4E2D\u67E5\u770B ${title}\uFF0C\u8FD9\u662F\u4E00\u4E2A ${ref.type === "artboard" ? "Artboard" : ref.type === "document" ? "Document" : "HTML"} Artifact\u3002` : `\u6D4F\u89C8 ${project} \u9879\u76EE\u7684\u5168\u90E8 Artboard\u3001Document \u548C HTML Artifact\uFF0C\u9884\u89C8\u771F\u5B9E\u5185\u5BB9\uFF0C\u6309\u7C7B\u578B\u3001\u540D\u79F0\u548C\u66F4\u65B0\u65F6\u95F4\u67E5\u627E\u4F5C\u54C1\u3002`;
85731
+ const canonical = `http://${urlHostForHttp(options.urlHost)}:${port}/${ref ? `${ref.type}/${ref.id}` : ""}`;
85732
+ const headers = {
85733
+ "Content-Type": "text/html; charset=utf-8",
85734
+ "Content-Security-Policy": PREVIEW_ROUTE.test(pathname) ? VIEWER_CSP.replace("frame-ancestors 'none'", "frame-ancestors 'self'") : VIEWER_CSP
85735
+ };
85680
85736
  if (key2 !== null) headers["Set-Cookie"] = `${cookieName}=${token}; HttpOnly; SameSite=Strict; Path=/`;
85681
- sendFile(res, import_node_path15.default.join(viewerDir, "index.html"), headers);
85737
+ void import_node_fs15.default.promises.readFile(import_node_path15.default.join(viewerDir, "index.html"), "utf8").then((template) => send(res, 200, viewerPage(template, { title, description, url: canonical }), headers)).catch((err) => send(res, err.code === "ENOENT" ? 404 : 500, "Viewer unavailable"));
85682
85738
  return;
85683
85739
  }
85684
85740
  const target = resolveInside(viewerDir, pathname.slice(1));
@@ -85761,6 +85817,8 @@ async function startArtifactsServer(options) {
85761
85817
  const dir = resolveArtifactDir(root, ref.type, ref.id);
85762
85818
  if (!dir) {
85763
85819
  signatures.delete(key2);
85820
+ const frame2 = textFrame(JSON.stringify({ type: "change", artifact: key2, files: changed }));
85821
+ for (const socket of clients) socket.write(frame2);
85764
85822
  continue;
85765
85823
  }
85766
85824
  if (ref.type === "document" && (changed.includes("doc.xml") || changed.length === 0)) documents.fileChanged(ref.id);
@@ -85926,7 +85984,10 @@ async function main() {
85926
85984
  if (launcher) (0, import_node_child_process.execFile)(launcher.bin, launcher.args, () => {
85927
85985
  });
85928
85986
  });
85987
+ let stopping = false;
85929
85988
  const shutdown = async (reason) => {
85989
+ if (stopping) return;
85990
+ stopping = true;
85930
85991
  console.log(JSON.stringify({ type: "server-stopped", reason }));
85931
85992
  import_node_fs17.default.rmSync(import_node_path16.default.join(stateDir, "server-info"), { force: true });
85932
85993
  writeJsonAtomic(import_node_path16.default.join(stateDir, "server-stopped"), { reason, timestamp: Date.now() });
@@ -0,0 +1,279 @@
1
+ #!/usr/bin/env bash
2
+ # Start the artifacts server for a project and print its connection info as JSON.
3
+ # Usage: start-server.sh [--project-dir <path>] [--artifact <type>/<id>] [--host <bind-host>]
4
+ # [--url-host <display-host>] [--idle-timeout-minutes <n>] [--open] [--no-open]
5
+ # [--foreground] [--background]
6
+ #
7
+ # --project-dir <path> Project root (default: current directory). Artifacts live in
8
+ # <path>/.ryugi/artifacts/<type>/<id>/ and persist after the server stops.
9
+ # --artifact <t>/<id> Also print "link", the URL that opens that artifact.
10
+ # --host <bind-host> Interface to bind (default 127.0.0.1). Use 0.0.0.0 in remote or
11
+ # containerized environments.
12
+ # --url-host <host> Hostname shown in the returned URL.
13
+ # --idle-timeout-minutes <n> Stop after n minutes without activity (default 240).
14
+ # --open Open the browser when the first artifact is ready (default).
15
+ # --no-open Do not open a browser (for headless or scripted use).
16
+ # --foreground Run in the current terminal instead of backgrounding.
17
+ # --background Force background mode (overrides the Codex/Windows auto-foreground).
18
+ #
19
+ # If a server is already running for the project, its info is printed with "reused": true.
20
+ # Every run registers the calling session as an owner; the server stops when all owners exit.
21
+
22
+ SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
23
+
24
+ PROJECT_DIR="$PWD"
25
+ FOREGROUND="false"
26
+ FORCE_BACKGROUND="false"
27
+ BIND_HOST="127.0.0.1"
28
+ URL_HOST=""
29
+ ARTIFACT=""
30
+ OPEN="${ARTIFACTS_OPEN:-1}"
31
+ while [[ $# -gt 0 ]]; do
32
+ case "$1" in
33
+ --project-dir) PROJECT_DIR="$2"; shift 2 ;;
34
+ --artifact)
35
+ if ! [[ "${2:-}" =~ ^(artboard|document|html)/[a-z0-9][a-z0-9-]*$ ]]; then
36
+ echo '{"error": "--artifact must be <type>/<id>: type artboard, document or html, id of lowercase letters, digits and hyphens"}'
37
+ exit 1
38
+ fi
39
+ ARTIFACT="$2"
40
+ shift 2
41
+ ;;
42
+ --host) BIND_HOST="$2"; shift 2 ;;
43
+ --url-host) URL_HOST="$2"; shift 2 ;;
44
+ --idle-timeout-minutes)
45
+ if ! [[ "$2" =~ ^[0-9]+$ ]] || [[ "$2" -lt 1 ]]; then
46
+ echo '{"error": "--idle-timeout-minutes must be a positive integer"}'
47
+ exit 1
48
+ fi
49
+ export ARTIFACTS_IDLE_TIMEOUT_MS=$(( $2 * 60 * 1000 ))
50
+ shift 2
51
+ ;;
52
+ --open) OPEN=1; shift ;;
53
+ --no-open) OPEN=0; shift ;;
54
+ --foreground|--no-daemon) FOREGROUND="true"; shift ;;
55
+ --background|--daemon) FORCE_BACKGROUND="true"; shift ;;
56
+ *) echo "{\"error\": \"Unknown argument: $1\"}"; exit 1 ;;
57
+ esac
58
+ done
59
+
60
+ if [[ -z "$URL_HOST" ]]; then
61
+ if [[ "$BIND_HOST" == "127.0.0.1" || "$BIND_HOST" == "localhost" ]]; then
62
+ URL_HOST="localhost"
63
+ else
64
+ URL_HOST="$BIND_HOST"
65
+ fi
66
+ fi
67
+
68
+ is_windows_like_shell() {
69
+ case "${OSTYPE:-}" in msys*|cygwin*|mingw*) return 0 ;; esac
70
+ [[ -n "${MSYSTEM:-}" ]] && return 0
71
+ case "$(uname -s 2>/dev/null || true)" in MSYS*|MINGW*|CYGWIN*) return 0 ;; esac
72
+ return 1
73
+ }
74
+
75
+ # Codex and Windows/Git Bash reap background processes.
76
+ if [[ "$FOREGROUND" != "true" && "$FORCE_BACKGROUND" != "true" ]]; then
77
+ if [[ -n "${CODEX_CI:-}" ]] || is_windows_like_shell; then
78
+ FOREGROUND="true"
79
+ fi
80
+ fi
81
+
82
+ # State files embed the session key; keep everything owner-only.
83
+ umask 077
84
+
85
+ if ! PROJECT_REAL="$(cd "$PROJECT_DIR" 2>/dev/null && pwd -P)"; then
86
+ echo "{\"error\": \"Project directory not found: $PROJECT_DIR\"}"
87
+ exit 1
88
+ fi
89
+ ROOT_DIR="$PROJECT_REAL/.ryugi/artifacts"
90
+ STATE_DIR="$ROOT_DIR/.state"
91
+ PID_FILE="$STATE_DIR/server.pid"
92
+ LOG_FILE="$STATE_DIR/server.log"
93
+ SERVER_ID_FILE="$STATE_DIR/server-instance-id"
94
+ INFO_FILE="$STATE_DIR/server-info"
95
+ OWNERS_FILE="$STATE_DIR/owners"
96
+ mkdir -p "$STATE_DIR"
97
+ [[ -f "$STATE_DIR/.gitignore" ]] || printf '*\n' > "$STATE_DIR/.gitignore"
98
+
99
+ # A local build (pnpm build:server) wins; otherwise run the release pinned in version.json,
100
+ # installed once per version. Runs before the project lock: a slow install must not outlive
101
+ # the lock's stale threshold. npm installs into a staging dir that is renamed into place;
102
+ # rename(2) refuses a non-empty target, so a concurrent start that finished first keeps its install.
103
+ resolve_server() {
104
+ if [[ -f "$SCRIPT_DIR/server.cjs" ]]; then
105
+ SERVER="$SCRIPT_DIR/server.cjs"
106
+ return 0
107
+ fi
108
+ local version cache staging
109
+ version="$(node -p 'require(process.argv[1]).version' "$SCRIPT_DIR/version.json")"
110
+ cache="${XDG_CACHE_HOME:-$HOME/.cache}/ryugi/artifacts/$version"
111
+ SERVER="$cache/node_modules/ryugi-artifacts/dist/server.cjs"
112
+ [[ -f "$SERVER" ]] && return 0
113
+ staging="$cache.install.$$"
114
+ rm -rf "$staging"
115
+ mkdir -p "$staging"
116
+ if ! npm install --prefix "$staging" --no-save --no-package-lock --no-audit --no-fund --loglevel=error \
117
+ "ryugi-artifacts@$version" > "$staging.log" 2>&1 || [[ ! -f "$staging/node_modules/ryugi-artifacts/dist/server.cjs" ]]; then
118
+ node -e 'console.log(JSON.stringify({ error: `Could not install ${process.argv[1]} from npm; the first start of each version needs network access and a writable ${process.argv[2]}, so rerun outside the sandbox. npm: ${process.argv[3].trim().split("\n").pop() || "failed"}` }))' \
119
+ "ryugi-artifacts@$version" "$(dirname "$cache")" "$(cat "$staging.log")"
120
+ rm -rf "$staging" "$staging.log"
121
+ return 1
122
+ fi
123
+ rm -f "$staging.log"
124
+ node -e 'try { require("node:fs").renameSync(process.argv[1], process.argv[2]) } catch {}' "$staging" "$cache"
125
+ rm -rf "$staging"
126
+ [[ -f "$SERVER" ]] && return 0
127
+ echo "{\"error\": \"Installed ryugi-artifacts@$version but could not move it into $cache\"}"
128
+ return 1
129
+ }
130
+
131
+ resolve_server || exit 1
132
+
133
+ # Concurrent runs for one project must not both spawn a server: hold a lock from the
134
+ # running-server check until the new server has written server-info.
135
+ LOCK_DIR="$STATE_DIR/start.lock"
136
+ release_lock() { rmdir "$LOCK_DIR" 2>/dev/null; return 0; }
137
+ acquire_lock() {
138
+ local _
139
+ for _ in {1..150}; do
140
+ if mkdir "$LOCK_DIR" 2>/dev/null; then
141
+ trap release_lock EXIT
142
+ return 0
143
+ fi
144
+ if [[ -n "$(find "$LOCK_DIR" -maxdepth 0 -mmin +1 2>/dev/null)" ]]; then
145
+ rmdir "$LOCK_DIR" 2>/dev/null
146
+ continue
147
+ fi
148
+ sleep 0.1
149
+ done
150
+ return 1
151
+ }
152
+ if ! acquire_lock; then
153
+ echo '{"error": "Another start-server.sh run for this project is still starting; retry in a moment"}'
154
+ exit 1
155
+ fi
156
+
157
+ command_has_server_id() {
158
+ local pid="$1" expected_arg="--artifacts-server-id=$2" arg command_line
159
+ if [[ -r "/proc/$pid/cmdline" ]]; then
160
+ while IFS= read -r -d '' arg || [[ -n "$arg" ]]; do
161
+ [[ "$arg" == "$expected_arg" ]] && return 0
162
+ done < "/proc/$pid/cmdline"
163
+ return 1
164
+ fi
165
+ command_line="$(ps -ww -p "$pid" -o command= 2>/dev/null || ps -f -p "$pid" 2>/dev/null | sed '1d' || true)"
166
+ case " $command_line " in
167
+ *" $expected_arg "*) return 0 ;;
168
+ *) return 1 ;;
169
+ esac
170
+ }
171
+
172
+ running_server_pid() {
173
+ [[ -f "$PID_FILE" && -f "$SERVER_ID_FILE" ]] || return 1
174
+ local pid id
175
+ pid="$(cat "$PID_FILE")"
176
+ id="$(tr -d '\r\n' < "$SERVER_ID_FILE")"
177
+ kill -0 "$pid" 2>/dev/null || return 1
178
+ command_has_server_id "$pid" "$id" || return 1
179
+ echo "$pid"
180
+ }
181
+
182
+ # $PPID is the throwaway shell the harness spawned for this script; the harness is its parent.
183
+ OWNER_PID="$(ps -o ppid= -p "$PPID" 2>/dev/null | tr -d ' ')"
184
+ if [[ -z "$OWNER_PID" || "$OWNER_PID" == "1" ]]; then
185
+ OWNER_PID="$PPID"
186
+ fi
187
+ # Node cannot see MSYS2 PIDs; an unverifiable owner would stop the server at the first check.
188
+ if is_windows_like_shell; then
189
+ OWNER_PID=""
190
+ fi
191
+
192
+ register_owner() {
193
+ local tmp="$OWNERS_FILE.$$" pid
194
+ {
195
+ if [[ -f "$OWNERS_FILE" ]]; then
196
+ while IFS= read -r pid; do
197
+ [[ "$pid" =~ ^[0-9]+$ ]] && kill -0 "$pid" 2>/dev/null && printf '%s\n' "$pid"
198
+ done < "$OWNERS_FILE"
199
+ fi
200
+ [[ -n "$OWNER_PID" ]] && printf '%s\n' "$OWNER_PID"
201
+ } | sort -u > "$tmp"
202
+ mv "$tmp" "$OWNERS_FILE"
203
+ }
204
+
205
+ # Prints the server info JSON with "link" for --artifact, and "reused" when $1 is true.
206
+ emit_info() {
207
+ node -e '
208
+ const [json, reused, artifact] = process.argv.slice(1);
209
+ const info = JSON.parse(json);
210
+ if (reused === "true") info.reused = true;
211
+ if (artifact) {
212
+ const url = new URL(info.url);
213
+ info.link = `${url.origin}/${artifact}?key=${url.searchParams.get("key")}`;
214
+ }
215
+ console.log(JSON.stringify(info));
216
+ ' "$1" "$2" "$ARTIFACT"
217
+ }
218
+
219
+ if running_server_pid >/dev/null && [[ -f "$INFO_FILE" ]]; then
220
+ register_owner
221
+ emit_info "$(cat "$INFO_FILE")" true
222
+ exit 0
223
+ fi
224
+
225
+ register_owner
226
+ rm -f "$INFO_FILE"
227
+
228
+ SERVER_ID=""
229
+ if [[ -r /dev/urandom ]]; then
230
+ SERVER_ID="$(od -An -N24 -tx1 /dev/urandom 2>/dev/null | tr -d ' \n' || true)"
231
+ fi
232
+ if ! [[ "$SERVER_ID" =~ ^[A-Za-z0-9_-]{32,64}$ ]]; then
233
+ SERVER_ID="$(printf '%08x%08x%08x%08x' "$$" "$(date +%s)" "${RANDOM:-0}" "${RANDOM:-0}")"
234
+ fi
235
+ printf '%s\n' "$SERVER_ID" > "$SERVER_ID_FILE"
236
+
237
+ SERVER_ENV=(ARTIFACTS_ROOT="$ROOT_DIR" ARTIFACTS_HOST="$BIND_HOST" ARTIFACTS_URL_HOST="$URL_HOST" ARTIFACTS_OPEN="$OPEN")
238
+ [[ -n "$ARTIFACT" ]] && SERVER_ENV+=(ARTIFACTS_OPEN_ARTIFACT="$ARTIFACT")
239
+
240
+ if [[ "$FOREGROUND" == "true" ]]; then
241
+ env "${SERVER_ENV[@]}" node "$SERVER" "--artifacts-server-id=$SERVER_ID" &
242
+ SERVER_PID=$!
243
+ echo "$SERVER_PID" > "$PID_FILE"
244
+ trap 'kill -TERM "$SERVER_PID" 2>/dev/null || true' INT TERM
245
+ for _ in {1..50}; do
246
+ [[ -f "$INFO_FILE" ]] && break
247
+ sleep 0.1
248
+ done
249
+ release_lock
250
+ wait "$SERVER_PID"
251
+ exit $?
252
+ fi
253
+
254
+ nohup env "${SERVER_ENV[@]}" node "$SERVER" "--artifacts-server-id=$SERVER_ID" > "$LOG_FILE" 2>&1 &
255
+ SERVER_PID=$!
256
+ disown "$SERVER_PID" 2>/dev/null
257
+ echo "$SERVER_PID" > "$PID_FILE"
258
+
259
+ for _ in {1..50}; do
260
+ if grep -q '"server-started"' "$LOG_FILE" 2>/dev/null; then
261
+ for _ in {1..20}; do
262
+ if ! kill -0 "$SERVER_PID" 2>/dev/null; then
263
+ echo "{\"error\": \"Server started but was killed. Retry in a persistent terminal with: $SCRIPT_DIR/start-server.sh --project-dir $PROJECT_REAL --host $BIND_HOST --url-host $URL_HOST --foreground\"}"
264
+ exit 1
265
+ fi
266
+ sleep 0.1
267
+ done
268
+ emit_info "$(grep '"server-started"' "$LOG_FILE" | head -1)" false
269
+ exit 0
270
+ fi
271
+ if grep -q '"server-error"' "$LOG_FILE" 2>/dev/null; then
272
+ grep '"server-error"' "$LOG_FILE" | head -1
273
+ exit 1
274
+ fi
275
+ sleep 0.1
276
+ done
277
+
278
+ echo '{"error": "Server failed to start within 5 seconds"}'
279
+ exit 1
@@ -1 +1 @@
1
- import{i as e}from"./rolldown-runtime-COiEfhsA.js";import{n as t,t as n}from"./jsx-runtime-CldxteV5.js";import{c as r,l as i,n as a,o,r as s,s as c}from"./DocumentEditor-RfVa-8pR.js";var l=e(t(),1),u=n();function d(){let e=(0,l.useMemo)(()=>window.matchMedia(`(prefers-color-scheme: dark)`),[]),[t,n]=(0,l.useState)(e.matches);return(0,l.useEffect)(()=>{let t=()=>n(e.matches);return e.addEventListener(`change`,t),()=>e.removeEventListener(`change`,t)},[e]),t}function f({id:e,state:t,contentBase:n}){let f=d(),p=(0,l.useMemo)(()=>({artifact:`cloud/${e}`,contentBase:n,channel:c(),send:()=>void 0}),[e,n]);return(0,l.useEffect)(()=>{let e=document.createElement(`base`);return e.href=n,document.head.prepend(e),()=>e.remove()},[n]),(0,u.jsx)(`div`,{className:`x1us19tq x1rozbrz xo2rkog`,className:`ryugi-doc ${{className:`x1us19tq x1rozbrz xo2rkog`}.className??``}`,children:(0,u.jsx)(`article`,{className:`xrgej4m xvueqy4 x1axd487 x4l9tsp`,children:(0,u.jsx)(o.Provider,{value:p,children:(0,u.jsx)(i,{variant:`article`,theme:f?`dark`:`light`,initialValue:t,extraNodes:a,rendererConfig:s,onEditorReady:e=>e?.setEditable(!1),children:(0,u.jsx)(r,{})})})})})}export{f as default};
1
+ import{i as e}from"./rolldown-runtime-COiEfhsA.js";import{n as t,t as n}from"./jsx-runtime-CldxteV5.js";import{c as r,l as i,n as a,o,r as s,s as c}from"./DocumentEditor-BS16Wb_Z.js";var l=e(t(),1),u=n();function d(){let e=(0,l.useMemo)(()=>window.matchMedia(`(prefers-color-scheme: dark)`),[]),[t,n]=(0,l.useState)(e.matches);return(0,l.useEffect)(()=>{let t=()=>n(e.matches);return e.addEventListener(`change`,t),()=>e.removeEventListener(`change`,t)},[e]),t}function f({id:e,state:t,contentBase:n}){let f=d(),p=(0,l.useMemo)(()=>({artifact:`cloud/${e}`,contentBase:n,channel:c(),send:()=>void 0}),[e,n]);return(0,l.useEffect)(()=>{let e=document.createElement(`base`);return e.href=n,document.head.prepend(e),()=>e.remove()},[n]),(0,u.jsx)(`div`,{className:`x1us19tq x1rozbrz xo2rkog`,className:`ryugi-doc ${{className:`x1us19tq x1rozbrz xo2rkog`}.className??``}`,children:(0,u.jsx)(`article`,{className:`xrgej4m xvueqy4 x1axd487 x4l9tsp`,children:(0,u.jsx)(o.Provider,{value:p,children:(0,u.jsx)(i,{variant:`article`,theme:f?`dark`:`light`,initialValue:t,extraNodes:a,rendererConfig:s,onEditorReady:e=>e?.setEditable(!1),children:(0,u.jsx)(r,{})})})})})}export{f as default};