@saluzi/saluzi-edu 0.5.21 → 0.6.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 (201) hide show
  1. package/dist/cli.js +444 -327
  2. package/dist/guide/guide-data.json +174 -174
  3. package/dist/rcs-web/assets/AdminPanel-D0fVkpU2.js +1 -0
  4. package/dist/rcs-web/assets/ArtifactView-DG0-kZ2G.js +1 -0
  5. package/{packages/remote-control-server/web/dist/assets/ArtifactsGallery-B63LTThv.js → dist/rcs-web/assets/ArtifactsGallery-CcobkOm1.js} +31 -31
  6. package/dist/rcs-web/assets/Claim-CltNvmRS.js +1 -0
  7. package/dist/rcs-web/assets/Dashboard-CEzuQ0N4.js +6 -0
  8. package/dist/rcs-web/assets/Join-DX0LzcPE.js +1 -0
  9. package/dist/rcs-web/assets/Login-BVKB4X_Z.js +1 -0
  10. package/dist/rcs-web/assets/Register-D-BrLVl3.js +1 -0
  11. package/dist/rcs-web/assets/RegisterEmpty-DdDXaiEn.js +26 -0
  12. package/dist/rcs-web/assets/SessionDetail-BkKSNMD8.js +78 -0
  13. package/dist/rcs-web/assets/{SessionVisibilityBadge-DA_Sg1dx.js → SessionVisibilityBadge-Ch3s2iFY.js} +2 -2
  14. package/dist/rcs-web/assets/Setup-CyGhRI5L.js +1 -0
  15. package/dist/rcs-web/assets/{ShareLanding-DaLDc5iV.js → ShareLanding-xKcBqmJb.js} +1 -1
  16. package/dist/rcs-web/assets/TeamDetail-C3Ne25hE.js +11 -0
  17. package/dist/rcs-web/assets/TeamList-C5Zyrj2-.js +1 -0
  18. package/dist/rcs-web/assets/TeamSettings-BsT93PQO.js +1 -0
  19. package/dist/rcs-web/assets/UserSearchInput-BFpwaVmp.js +6 -0
  20. package/dist/rcs-web/assets/UserSettings-cIzS243Z.js +1 -0
  21. package/dist/rcs-web/assets/{arc-CPhgreP8.js → arc-CiWQl09E.js} +1 -1
  22. package/dist/rcs-web/assets/{architectureDiagram-3BPJPVTR-CpAi-qzk.js → architectureDiagram-3BPJPVTR-DL5Id6fa.js} +1 -1
  23. package/{packages/remote-control-server/web/dist/assets/blockDiagram-GPEHLZMM-DcsxgO1K.js → dist/rcs-web/assets/blockDiagram-GPEHLZMM-DF-nk9Fe.js} +1 -1
  24. package/{packages/remote-control-server/web/dist/assets/c4Diagram-AAUBKEIU-BQ5cjzbZ.js → dist/rcs-web/assets/c4Diagram-AAUBKEIU-l_Pl6m2J.js} +1 -1
  25. package/dist/rcs-web/assets/channel-CBq46cRr.js +1 -0
  26. package/dist/rcs-web/assets/{chunk-2J33WTMH-wa-oCiR6.js → chunk-2J33WTMH-Dr5xQSXu.js} +1 -1
  27. package/dist/rcs-web/assets/{chunk-4BX2VUAB-D2ybEyPG.js → chunk-4BX2VUAB-DAPTU1FG.js} +1 -1
  28. package/dist/rcs-web/assets/{chunk-55IACEB6-CQGtwyGQ.js → chunk-55IACEB6-BgaGrvZR.js} +1 -1
  29. package/{packages/remote-control-server/web/dist/assets/chunk-727SXJPM-D0ITaMeP.js → dist/rcs-web/assets/chunk-727SXJPM-D6dnSxU3.js} +1 -1
  30. package/{packages/remote-control-server/web/dist/assets/chunk-AQP2D5EJ-BWRrcP1d.js → dist/rcs-web/assets/chunk-AQP2D5EJ-BVCad_JN.js} +1 -1
  31. package/dist/rcs-web/assets/{chunk-FMBD7UC4-C-CaLwfI.js → chunk-FMBD7UC4-BNLx608W.js} +1 -1
  32. package/dist/rcs-web/assets/{chunk-ND2GUHAM-OPpmIsi8.js → chunk-ND2GUHAM-BAHk1eiL.js} +1 -1
  33. package/dist/rcs-web/assets/{chunk-QZHKN3VN-Bq6R2yM7.js → chunk-QZHKN3VN-CX_4LT0M.js} +1 -1
  34. package/dist/rcs-web/assets/classDiagram-4FO5ZUOK-CYdZp3iH.js +1 -0
  35. package/dist/rcs-web/assets/classDiagram-v2-Q7XG4LA2-CYdZp3iH.js +1 -0
  36. package/{packages/remote-control-server/web/dist/assets/code-block-IT6T5CEO-BQf-xjVa.js → dist/rcs-web/assets/code-block-IT6T5CEO-BoFB9z5v.js} +1 -1
  37. package/dist/rcs-web/assets/{copy-lzYYFmlH.js → copy-EPASKX-X.js} +1 -1
  38. package/{packages/remote-control-server/web/dist/assets/cose-bilkent-S5V4N54A-CuUSRgoZ.js → dist/rcs-web/assets/cose-bilkent-S5V4N54A-CMpuIlrx.js} +1 -1
  39. package/{packages/remote-control-server/web/dist/assets/dagre-BM42HDAG-BP4ZP_3D.js → dist/rcs-web/assets/dagre-BM42HDAG-Dg4Q9j21.js} +1 -1
  40. package/dist/rcs-web/assets/{diagram-2AECGRRQ-XQnH0b9k.js → diagram-2AECGRRQ-YGGSegJh.js} +1 -1
  41. package/dist/rcs-web/assets/{diagram-5GNKFQAL-BnuYmMPD.js → diagram-5GNKFQAL-Rg7tQ7zl.js} +1 -1
  42. package/{packages/remote-control-server/web/dist/assets/diagram-KO2AKTUF-LymV4oAW.js → dist/rcs-web/assets/diagram-KO2AKTUF-FwQUsRJf.js} +1 -1
  43. package/dist/rcs-web/assets/{diagram-LMA3HP47-NSg5NWFp.js → diagram-LMA3HP47-DDzZwu_E.js} +1 -1
  44. package/dist/rcs-web/assets/{diagram-OG6HWLK6-kVTMFgtZ.js → diagram-OG6HWLK6-D6Pxp9XO.js} +1 -1
  45. package/dist/rcs-web/assets/dialog-Ort95zkZ.js +1 -0
  46. package/dist/rcs-web/assets/{erDiagram-TEJ5UH35-BJBTtX2s.js → erDiagram-TEJ5UH35-BSDAq23h.js} +1 -1
  47. package/dist/rcs-web/assets/{flowDiagram-I6XJVG4X-CcQXZNID.js → flowDiagram-I6XJVG4X-CzWT0vwA.js} +1 -1
  48. package/{packages/remote-control-server/web/dist/assets/ganttDiagram-6RSMTGT7-DW8iKyq_.js → dist/rcs-web/assets/ganttDiagram-6RSMTGT7-DPNJQ_Co.js} +1 -1
  49. package/{packages/remote-control-server/web/dist/assets/gitGraphDiagram-PVQCEYII-BTBYx3LF.js → dist/rcs-web/assets/gitGraphDiagram-PVQCEYII-vHpFxzAD.js} +1 -1
  50. package/dist/rcs-web/assets/{infoDiagram-5YYISTIA-BRZAYc6t.js → infoDiagram-5YYISTIA-Bk_F8hwq.js} +1 -1
  51. package/{packages/remote-control-server/web/dist/assets/ishikawaDiagram-YF4QCWOH-BYMQtEeD.js → dist/rcs-web/assets/ishikawaDiagram-YF4QCWOH-CBYfpD17.js} +1 -1
  52. package/{packages/remote-control-server/web/dist/assets/journeyDiagram-JHISSGLW-aqx7w1db.js → dist/rcs-web/assets/journeyDiagram-JHISSGLW-BxoYxLNN.js} +1 -1
  53. package/{packages/remote-control-server/web/dist/assets/kanban-definition-UN3LZRKU-BxEHfP4O.js → dist/rcs-web/assets/kanban-definition-UN3LZRKU-B5pCpO1z.js} +1 -1
  54. package/dist/rcs-web/assets/{linear-Chjw8hPE.js → linear-BpcrEfNA.js} +1 -1
  55. package/dist/rcs-web/assets/main-BC4mcO_f.js +393 -0
  56. package/dist/rcs-web/assets/main-C0n90aVY.css +1 -0
  57. package/{packages/remote-control-server/web/dist/assets/mermaid-VLURNSYL-CrqI4db6.js → dist/rcs-web/assets/mermaid-VLURNSYL-DWwqH0oB.js} +4 -4
  58. package/dist/rcs-web/assets/{mermaid.core-EjsI3GC3.js → mermaid.core-CPGFiRhL.js} +5 -5
  59. package/dist/rcs-web/assets/{mindmap-definition-RKZ34NQL-D2rO_fGA.js → mindmap-definition-RKZ34NQL-DBF7JLl0.js} +1 -1
  60. package/dist/rcs-web/assets/{notifications-WMIbgYDP.js → notifications-C7DetfWu.js} +1 -1
  61. package/dist/rcs-web/assets/{pieDiagram-4H26LBE5-DDwJZfoh.js → pieDiagram-4H26LBE5-CbUgqUZY.js} +1 -1
  62. package/dist/rcs-web/assets/{quadrantDiagram-W4KKPZXB-DDtqMwKx.js → quadrantDiagram-W4KKPZXB-BUF-YWIU.js} +1 -1
  63. package/dist/rcs-web/assets/{refresh-cw-l0u8pxJi.js → refresh-cw-DBXI7gD3.js} +1 -1
  64. package/{packages/remote-control-server/web/dist/assets/requirementDiagram-4Y6WPE33-BtSk2-5u.js → dist/rcs-web/assets/requirementDiagram-4Y6WPE33-B8fyHxTP.js} +1 -1
  65. package/dist/rcs-web/assets/{sankeyDiagram-5OEKKPKP-SDLDMxUT.js → sankeyDiagram-5OEKKPKP-DAZKpwBw.js} +1 -1
  66. package/dist/rcs-web/assets/{sequenceDiagram-3UESZ5HK-D7iAclg1.js → sequenceDiagram-3UESZ5HK-DamEgVx-.js} +1 -1
  67. package/dist/rcs-web/assets/{stateDiagram-AJRCARHV-Bxx23fZH.js → stateDiagram-AJRCARHV-DU-QvteV.js} +1 -1
  68. package/dist/rcs-web/assets/{stateDiagram-v2-BHNVJYJU-z1g82auz.js → stateDiagram-v2-BHNVJYJU-C5QVbdY9.js} +1 -1
  69. package/dist/rcs-web/assets/{timeline-definition-PNZ67QCA-C8kBbm_V.js → timeline-definition-PNZ67QCA-Df0hGAH6.js} +1 -1
  70. package/dist/rcs-web/assets/{vennDiagram-CIIHVFJN-CPldb1-R.js → vennDiagram-CIIHVFJN-DbX36wdR.js} +1 -1
  71. package/{packages/remote-control-server/web/dist/assets/wardleyDiagram-YWT4CUSO-MCHB2fG7.js → dist/rcs-web/assets/wardleyDiagram-YWT4CUSO-rjVkCTKo.js} +1 -1
  72. package/dist/rcs-web/assets/workerType-gCLCeJDi.js +6 -0
  73. package/dist/rcs-web/assets/{xychartDiagram-2RQKCTM6-CHj-KmL6.js → xychartDiagram-2RQKCTM6-CHjulBZn.js} +1 -1
  74. package/dist/rcs-web/index.html +2 -2
  75. package/package.json +2 -1
  76. package/packages/remote-control-server/src/__tests__/backgroundTaskPipeline.test.ts +216 -0
  77. package/packages/remote-control-server/src/__tests__/client-ip.test.ts +67 -0
  78. package/packages/remote-control-server/src/__tests__/teams.test.ts +44 -0
  79. package/packages/remote-control-server/src/client-ip.ts +57 -0
  80. package/packages/remote-control-server/src/db/sqlite.ts +22 -0
  81. package/packages/remote-control-server/src/routes/v1/environments.ts +4 -0
  82. package/packages/remote-control-server/src/routes/web/teams.ts +12 -1
  83. package/packages/remote-control-server/src/services/environment.ts +12 -0
  84. package/packages/remote-control-server/src/store.ts +37 -8
  85. package/packages/remote-control-server/src/types/api.ts +7 -0
  86. package/packages/remote-control-server/web/dist/assets/AdminPanel-D0fVkpU2.js +1 -0
  87. package/packages/remote-control-server/web/dist/assets/ArtifactView-DG0-kZ2G.js +1 -0
  88. package/{dist/rcs-web/assets/ArtifactsGallery-B63LTThv.js → packages/remote-control-server/web/dist/assets/ArtifactsGallery-CcobkOm1.js} +31 -31
  89. package/packages/remote-control-server/web/dist/assets/Claim-CltNvmRS.js +1 -0
  90. package/packages/remote-control-server/web/dist/assets/Dashboard-CEzuQ0N4.js +6 -0
  91. package/packages/remote-control-server/web/dist/assets/Join-DX0LzcPE.js +1 -0
  92. package/packages/remote-control-server/web/dist/assets/Login-BVKB4X_Z.js +1 -0
  93. package/packages/remote-control-server/web/dist/assets/Register-D-BrLVl3.js +1 -0
  94. package/packages/remote-control-server/web/dist/assets/RegisterEmpty-DdDXaiEn.js +26 -0
  95. package/packages/remote-control-server/web/dist/assets/SessionDetail-BkKSNMD8.js +78 -0
  96. package/packages/remote-control-server/web/dist/assets/{SessionVisibilityBadge-DA_Sg1dx.js → SessionVisibilityBadge-Ch3s2iFY.js} +2 -2
  97. package/packages/remote-control-server/web/dist/assets/Setup-CyGhRI5L.js +1 -0
  98. package/packages/remote-control-server/web/dist/assets/{ShareLanding-DaLDc5iV.js → ShareLanding-xKcBqmJb.js} +1 -1
  99. package/packages/remote-control-server/web/dist/assets/TeamDetail-C3Ne25hE.js +11 -0
  100. package/packages/remote-control-server/web/dist/assets/TeamList-C5Zyrj2-.js +1 -0
  101. package/packages/remote-control-server/web/dist/assets/TeamSettings-BsT93PQO.js +1 -0
  102. package/packages/remote-control-server/web/dist/assets/UserSearchInput-BFpwaVmp.js +6 -0
  103. package/packages/remote-control-server/web/dist/assets/UserSettings-cIzS243Z.js +1 -0
  104. package/packages/remote-control-server/web/dist/assets/{arc-CPhgreP8.js → arc-CiWQl09E.js} +1 -1
  105. package/packages/remote-control-server/web/dist/assets/{architectureDiagram-3BPJPVTR-CpAi-qzk.js → architectureDiagram-3BPJPVTR-DL5Id6fa.js} +1 -1
  106. package/{dist/rcs-web/assets/blockDiagram-GPEHLZMM-DcsxgO1K.js → packages/remote-control-server/web/dist/assets/blockDiagram-GPEHLZMM-DF-nk9Fe.js} +1 -1
  107. package/{dist/rcs-web/assets/c4Diagram-AAUBKEIU-BQ5cjzbZ.js → packages/remote-control-server/web/dist/assets/c4Diagram-AAUBKEIU-l_Pl6m2J.js} +1 -1
  108. package/packages/remote-control-server/web/dist/assets/channel-CBq46cRr.js +1 -0
  109. package/packages/remote-control-server/web/dist/assets/{chunk-2J33WTMH-wa-oCiR6.js → chunk-2J33WTMH-Dr5xQSXu.js} +1 -1
  110. package/packages/remote-control-server/web/dist/assets/{chunk-4BX2VUAB-D2ybEyPG.js → chunk-4BX2VUAB-DAPTU1FG.js} +1 -1
  111. package/packages/remote-control-server/web/dist/assets/{chunk-55IACEB6-CQGtwyGQ.js → chunk-55IACEB6-BgaGrvZR.js} +1 -1
  112. package/{dist/rcs-web/assets/chunk-727SXJPM-D0ITaMeP.js → packages/remote-control-server/web/dist/assets/chunk-727SXJPM-D6dnSxU3.js} +1 -1
  113. package/{dist/rcs-web/assets/chunk-AQP2D5EJ-BWRrcP1d.js → packages/remote-control-server/web/dist/assets/chunk-AQP2D5EJ-BVCad_JN.js} +1 -1
  114. package/packages/remote-control-server/web/dist/assets/{chunk-FMBD7UC4-C-CaLwfI.js → chunk-FMBD7UC4-BNLx608W.js} +1 -1
  115. package/packages/remote-control-server/web/dist/assets/{chunk-ND2GUHAM-OPpmIsi8.js → chunk-ND2GUHAM-BAHk1eiL.js} +1 -1
  116. package/packages/remote-control-server/web/dist/assets/{chunk-QZHKN3VN-Bq6R2yM7.js → chunk-QZHKN3VN-CX_4LT0M.js} +1 -1
  117. package/packages/remote-control-server/web/dist/assets/classDiagram-4FO5ZUOK-CYdZp3iH.js +1 -0
  118. package/packages/remote-control-server/web/dist/assets/classDiagram-v2-Q7XG4LA2-CYdZp3iH.js +1 -0
  119. package/{dist/rcs-web/assets/code-block-IT6T5CEO-BQf-xjVa.js → packages/remote-control-server/web/dist/assets/code-block-IT6T5CEO-BoFB9z5v.js} +1 -1
  120. package/packages/remote-control-server/web/dist/assets/{copy-lzYYFmlH.js → copy-EPASKX-X.js} +1 -1
  121. package/{dist/rcs-web/assets/cose-bilkent-S5V4N54A-CuUSRgoZ.js → packages/remote-control-server/web/dist/assets/cose-bilkent-S5V4N54A-CMpuIlrx.js} +1 -1
  122. package/{dist/rcs-web/assets/dagre-BM42HDAG-BP4ZP_3D.js → packages/remote-control-server/web/dist/assets/dagre-BM42HDAG-Dg4Q9j21.js} +1 -1
  123. package/packages/remote-control-server/web/dist/assets/{diagram-2AECGRRQ-XQnH0b9k.js → diagram-2AECGRRQ-YGGSegJh.js} +1 -1
  124. package/packages/remote-control-server/web/dist/assets/{diagram-5GNKFQAL-BnuYmMPD.js → diagram-5GNKFQAL-Rg7tQ7zl.js} +1 -1
  125. package/{dist/rcs-web/assets/diagram-KO2AKTUF-LymV4oAW.js → packages/remote-control-server/web/dist/assets/diagram-KO2AKTUF-FwQUsRJf.js} +1 -1
  126. package/packages/remote-control-server/web/dist/assets/{diagram-LMA3HP47-NSg5NWFp.js → diagram-LMA3HP47-DDzZwu_E.js} +1 -1
  127. package/packages/remote-control-server/web/dist/assets/{diagram-OG6HWLK6-kVTMFgtZ.js → diagram-OG6HWLK6-D6Pxp9XO.js} +1 -1
  128. package/packages/remote-control-server/web/dist/assets/dialog-Ort95zkZ.js +1 -0
  129. package/packages/remote-control-server/web/dist/assets/{erDiagram-TEJ5UH35-BJBTtX2s.js → erDiagram-TEJ5UH35-BSDAq23h.js} +1 -1
  130. package/packages/remote-control-server/web/dist/assets/{flowDiagram-I6XJVG4X-CcQXZNID.js → flowDiagram-I6XJVG4X-CzWT0vwA.js} +1 -1
  131. package/{dist/rcs-web/assets/ganttDiagram-6RSMTGT7-DW8iKyq_.js → packages/remote-control-server/web/dist/assets/ganttDiagram-6RSMTGT7-DPNJQ_Co.js} +1 -1
  132. package/{dist/rcs-web/assets/gitGraphDiagram-PVQCEYII-BTBYx3LF.js → packages/remote-control-server/web/dist/assets/gitGraphDiagram-PVQCEYII-vHpFxzAD.js} +1 -1
  133. package/packages/remote-control-server/web/dist/assets/{infoDiagram-5YYISTIA-BRZAYc6t.js → infoDiagram-5YYISTIA-Bk_F8hwq.js} +1 -1
  134. package/{dist/rcs-web/assets/ishikawaDiagram-YF4QCWOH-BYMQtEeD.js → packages/remote-control-server/web/dist/assets/ishikawaDiagram-YF4QCWOH-CBYfpD17.js} +1 -1
  135. package/{dist/rcs-web/assets/journeyDiagram-JHISSGLW-aqx7w1db.js → packages/remote-control-server/web/dist/assets/journeyDiagram-JHISSGLW-BxoYxLNN.js} +1 -1
  136. package/{dist/rcs-web/assets/kanban-definition-UN3LZRKU-BxEHfP4O.js → packages/remote-control-server/web/dist/assets/kanban-definition-UN3LZRKU-B5pCpO1z.js} +1 -1
  137. package/packages/remote-control-server/web/dist/assets/{linear-Chjw8hPE.js → linear-BpcrEfNA.js} +1 -1
  138. package/packages/remote-control-server/web/dist/assets/main-BC4mcO_f.js +393 -0
  139. package/packages/remote-control-server/web/dist/assets/main-C0n90aVY.css +1 -0
  140. package/{dist/rcs-web/assets/mermaid-VLURNSYL-CrqI4db6.js → packages/remote-control-server/web/dist/assets/mermaid-VLURNSYL-DWwqH0oB.js} +4 -4
  141. package/packages/remote-control-server/web/dist/assets/{mermaid.core-EjsI3GC3.js → mermaid.core-CPGFiRhL.js} +5 -5
  142. package/packages/remote-control-server/web/dist/assets/{mindmap-definition-RKZ34NQL-D2rO_fGA.js → mindmap-definition-RKZ34NQL-DBF7JLl0.js} +1 -1
  143. package/packages/remote-control-server/web/dist/assets/{notifications-WMIbgYDP.js → notifications-C7DetfWu.js} +1 -1
  144. package/packages/remote-control-server/web/dist/assets/{pieDiagram-4H26LBE5-DDwJZfoh.js → pieDiagram-4H26LBE5-CbUgqUZY.js} +1 -1
  145. package/packages/remote-control-server/web/dist/assets/{quadrantDiagram-W4KKPZXB-DDtqMwKx.js → quadrantDiagram-W4KKPZXB-BUF-YWIU.js} +1 -1
  146. package/packages/remote-control-server/web/dist/assets/{refresh-cw-l0u8pxJi.js → refresh-cw-DBXI7gD3.js} +1 -1
  147. package/{dist/rcs-web/assets/requirementDiagram-4Y6WPE33-BtSk2-5u.js → packages/remote-control-server/web/dist/assets/requirementDiagram-4Y6WPE33-B8fyHxTP.js} +1 -1
  148. package/packages/remote-control-server/web/dist/assets/{sankeyDiagram-5OEKKPKP-SDLDMxUT.js → sankeyDiagram-5OEKKPKP-DAZKpwBw.js} +1 -1
  149. package/packages/remote-control-server/web/dist/assets/{sequenceDiagram-3UESZ5HK-D7iAclg1.js → sequenceDiagram-3UESZ5HK-DamEgVx-.js} +1 -1
  150. package/packages/remote-control-server/web/dist/assets/{stateDiagram-AJRCARHV-Bxx23fZH.js → stateDiagram-AJRCARHV-DU-QvteV.js} +1 -1
  151. package/packages/remote-control-server/web/dist/assets/{stateDiagram-v2-BHNVJYJU-z1g82auz.js → stateDiagram-v2-BHNVJYJU-C5QVbdY9.js} +1 -1
  152. package/packages/remote-control-server/web/dist/assets/{timeline-definition-PNZ67QCA-C8kBbm_V.js → timeline-definition-PNZ67QCA-Df0hGAH6.js} +1 -1
  153. package/packages/remote-control-server/web/dist/assets/{vennDiagram-CIIHVFJN-CPldb1-R.js → vennDiagram-CIIHVFJN-DbX36wdR.js} +1 -1
  154. package/{dist/rcs-web/assets/wardleyDiagram-YWT4CUSO-MCHB2fG7.js → packages/remote-control-server/web/dist/assets/wardleyDiagram-YWT4CUSO-rjVkCTKo.js} +1 -1
  155. package/packages/remote-control-server/web/dist/assets/workerType-gCLCeJDi.js +6 -0
  156. package/packages/remote-control-server/web/dist/assets/{xychartDiagram-2RQKCTM6-CHj-KmL6.js → xychartDiagram-2RQKCTM6-CHjulBZn.js} +1 -1
  157. package/packages/remote-control-server/web/dist/index.html +2 -2
  158. package/dist/rcs-web/assets/AdminPanel-fsacwgfK.js +0 -1
  159. package/dist/rcs-web/assets/ArtifactView-DmMwrTRk.js +0 -1
  160. package/dist/rcs-web/assets/Claim-hOGNTz-n.js +0 -1
  161. package/dist/rcs-web/assets/Dashboard-BBIlAMpr.js +0 -6
  162. package/dist/rcs-web/assets/Join-zelwrNDz.js +0 -1
  163. package/dist/rcs-web/assets/Login-BmYeCfbw.js +0 -1
  164. package/dist/rcs-web/assets/Register-Dfw4S_A0.js +0 -1
  165. package/dist/rcs-web/assets/SessionDetail-zXHv84SV.js +0 -83
  166. package/dist/rcs-web/assets/Setup-BTTET7Rk.js +0 -1
  167. package/dist/rcs-web/assets/TeamCreate-BWtaB-_Z.js +0 -1
  168. package/dist/rcs-web/assets/TeamDetail-Crmn6PaC.js +0 -6
  169. package/dist/rcs-web/assets/TeamList-B8Rob6VK.js +0 -1
  170. package/dist/rcs-web/assets/TeamSettings-CfRHolhe.js +0 -1
  171. package/dist/rcs-web/assets/UserSearchInput-DkaGgR76.js +0 -1
  172. package/dist/rcs-web/assets/UserSettings-D1oW7oVv.js +0 -1
  173. package/dist/rcs-web/assets/channel-DHj-rIRW.js +0 -1
  174. package/dist/rcs-web/assets/classDiagram-4FO5ZUOK-DsAw9J1B.js +0 -1
  175. package/dist/rcs-web/assets/classDiagram-v2-Q7XG4LA2-DsAw9J1B.js +0 -1
  176. package/dist/rcs-web/assets/dialog-DrDf89nL.js +0 -1
  177. package/dist/rcs-web/assets/main-CJvwpIVn.css +0 -1
  178. package/dist/rcs-web/assets/main-Dh-rPGBg.js +0 -275
  179. package/dist/rcs-web/assets/workerType-BOi1t0TG.js +0 -1
  180. package/packages/remote-control-server/web/dist/assets/AdminPanel-fsacwgfK.js +0 -1
  181. package/packages/remote-control-server/web/dist/assets/ArtifactView-DmMwrTRk.js +0 -1
  182. package/packages/remote-control-server/web/dist/assets/Claim-hOGNTz-n.js +0 -1
  183. package/packages/remote-control-server/web/dist/assets/Dashboard-BBIlAMpr.js +0 -6
  184. package/packages/remote-control-server/web/dist/assets/Join-zelwrNDz.js +0 -1
  185. package/packages/remote-control-server/web/dist/assets/Login-BmYeCfbw.js +0 -1
  186. package/packages/remote-control-server/web/dist/assets/Register-Dfw4S_A0.js +0 -1
  187. package/packages/remote-control-server/web/dist/assets/SessionDetail-zXHv84SV.js +0 -83
  188. package/packages/remote-control-server/web/dist/assets/Setup-BTTET7Rk.js +0 -1
  189. package/packages/remote-control-server/web/dist/assets/TeamCreate-BWtaB-_Z.js +0 -1
  190. package/packages/remote-control-server/web/dist/assets/TeamDetail-Crmn6PaC.js +0 -6
  191. package/packages/remote-control-server/web/dist/assets/TeamList-B8Rob6VK.js +0 -1
  192. package/packages/remote-control-server/web/dist/assets/TeamSettings-CfRHolhe.js +0 -1
  193. package/packages/remote-control-server/web/dist/assets/UserSearchInput-DkaGgR76.js +0 -1
  194. package/packages/remote-control-server/web/dist/assets/UserSettings-D1oW7oVv.js +0 -1
  195. package/packages/remote-control-server/web/dist/assets/channel-DHj-rIRW.js +0 -1
  196. package/packages/remote-control-server/web/dist/assets/classDiagram-4FO5ZUOK-DsAw9J1B.js +0 -1
  197. package/packages/remote-control-server/web/dist/assets/classDiagram-v2-Q7XG4LA2-DsAw9J1B.js +0 -1
  198. package/packages/remote-control-server/web/dist/assets/dialog-DrDf89nL.js +0 -1
  199. package/packages/remote-control-server/web/dist/assets/main-CJvwpIVn.css +0 -1
  200. package/packages/remote-control-server/web/dist/assets/main-Dh-rPGBg.js +0 -275
  201. package/packages/remote-control-server/web/dist/assets/workerType-BOi1t0TG.js +0 -1
@@ -0,0 +1,57 @@
1
+ import type { Context } from 'hono'
2
+
3
+ /**
4
+ * Best-effort client (peer) address for an incoming request.
5
+ *
6
+ * Cross-runtime: RCS serves via Bun.serve (index.ts) in the bundled CLI and
7
+ * via @hono/node-server (nodeServer.ts) under Node. Bun passes the Server
8
+ * object as `c.env` (which exposes `requestIP()`); @hono/node-server exposes
9
+ * the raw socket at `c.env.incoming.socket.remoteAddress`. Proxied
10
+ * deployments (Docker + reverse proxy) put the real address in
11
+ * X-Forwarded-For / X-Real-IP, which win when present.
12
+ *
13
+ * Returns null when no address can be resolved — callers must treat the IP
14
+ * as optional (the Web UI omits it rather than rendering a blank).
15
+ *
16
+ * Client-supplied headers are untrusted: this value is display-only (an
17
+ * environment row's "where did this connect from"), never used for access
18
+ * control.
19
+ */
20
+ export function getClientIp(c: Context): string | null {
21
+ const forwarded = c.req.header('x-forwarded-for')
22
+ if (forwarded) {
23
+ const first = forwarded.split(',')[0]?.trim()
24
+ if (first) return normalizeIp(first)
25
+ }
26
+ const real = c.req.header('x-real-ip')
27
+ if (real?.trim()) return normalizeIp(real.trim())
28
+
29
+ const env = c.env as unknown as
30
+ | {
31
+ requestIP?: (req: Request) => { address?: string } | null
32
+ incoming?: { socket?: { remoteAddress?: string } }
33
+ }
34
+ | undefined
35
+
36
+ // Bun.serve: the server object exposes requestIP(request).
37
+ try {
38
+ const info = env?.requestIP?.(c.req.raw)
39
+ if (info?.address) return normalizeIp(info.address)
40
+ } catch {
41
+ /* not available on this runtime */
42
+ }
43
+
44
+ // @hono/node-server: raw Node socket.
45
+ const remote = env?.incoming?.socket?.remoteAddress
46
+ if (remote) return normalizeIp(remote)
47
+
48
+ return null
49
+ }
50
+
51
+ /** Map IPv4-mapped IPv6 (`::ffff:127.0.0.1`) to its IPv4 form; strip brackets. */
52
+ function normalizeIp(addr: string): string {
53
+ const v = addr.trim()
54
+ if (v.startsWith('::ffff:')) return v.slice('::ffff:'.length)
55
+ if (v.startsWith('[') && v.endsWith(']')) return v.slice(1, -1)
56
+ return v
57
+ }
@@ -173,6 +173,28 @@ export function migrateDatabase(db: Database): void {
173
173
  // all columns.
174
174
  migrateEnvironmentsColumns(db)
175
175
  db.exec(schema)
176
+ releaseDeletedTeamSlugs(db)
177
+ }
178
+
179
+ /**
180
+ * Release the slugs of teams soft-deleted before DELETE /teams/:id learned to
181
+ * rename the slug on delete. `teams.slug` carries an unconditional UNIQUE
182
+ * constraint, so a deleted row keeps its slug reserved; the create-time
183
+ * uniqueness check only looks at live rows, which made re-creating a team with
184
+ * a previously deleted slug fail on the index after passing the check.
185
+ * Idempotent: the `-deleted-` marker skips rows already released (either by
186
+ * the delete handler or by a previous run of this migration).
187
+ */
188
+ function releaseDeletedTeamSlugs(db: Database): void {
189
+ const tableExists = db
190
+ .query("SELECT 1 FROM sqlite_master WHERE type='table' AND name='teams'")
191
+ .get() as { 1: number } | undefined
192
+ if (!tableExists) return
193
+
194
+ db.query(
195
+ `UPDATE teams SET slug = slug || '-deleted-' || id
196
+ WHERE deleted_at IS NOT NULL AND slug NOT LIKE '%-deleted-%'`,
197
+ ).run()
176
198
  }
177
199
 
178
200
  /**
@@ -14,6 +14,7 @@ import {
14
14
  resolveUserIdUuid,
15
15
  } from '../../auth/bridge-auth'
16
16
  import { getDb } from '../../db/sqlite'
17
+ import { getClientIp } from '../../client-ip'
17
18
  import { isSessionClosedStatus } from '../../services/session'
18
19
  import { getSingleUserAdminUuid } from '../../services/single-user'
19
20
  import {
@@ -241,6 +242,9 @@ app.post('/bridge', acceptCliHeaders, bridgeAuth, async c => {
241
242
  const result = registerEnvironment({
242
243
  ...body,
243
244
  username,
245
+ // Peer address captured at registration — surfaced in the Web UI's
246
+ // environment list so a machine is identifiable beyond its hostname.
247
+ ipAddress: getClientIp(c),
244
248
  ownerUserId,
245
249
  teamId: teamId || null,
246
250
  claimToken,
@@ -387,8 +387,19 @@ app.delete('/teams/:id', withAuth, async c => {
387
387
  }
388
388
 
389
389
  const now = new Date().toISOString()
390
- db.query('UPDATE teams SET deleted_at = $now WHERE id = $id').run({
390
+ // Soft delete AND release the slug. `teams.slug` carries an unconditional
391
+ // UNIQUE constraint, while the create-time uniqueness check only looks at
392
+ // live rows (`deleted_at IS NULL`) — so without renaming here a deleted team
393
+ // would hold its slug forever and re-creating a team with the same slug
394
+ // would pass the check yet fail the INSERT on the index. The archived value
395
+ // is unique (teamId is the PK) and inert: deleted teams are only addressed
396
+ // by id (by-slug and every list filter exclude `deleted_at`).
397
+ const teamSlug = String(result.team.slug ?? '')
398
+ db.query(
399
+ 'UPDATE teams SET deleted_at = $now, slug = $slug WHERE id = $id',
400
+ ).run({
391
401
  $now: now,
402
+ $slug: `${teamSlug}-deleted-${teamId}`,
392
403
  $id: teamId,
393
404
  })
394
405
 
@@ -30,6 +30,7 @@ function toResponse(
30
30
  teamId?: string | null
31
31
  teamName?: string | null
32
32
  ownerUserId?: string | null
33
+ ownerUsername?: string | null
33
34
  },
34
35
  ): EnvironmentResponse {
35
36
  return {
@@ -39,13 +40,18 @@ function toResponse(
39
40
  branch: row.branch,
40
41
  status: row.status,
41
42
  username: row.username,
43
+ ip_address: row.ipAddress,
42
44
  last_poll_at: row.lastPollAt ? row.lastPollAt.getTime() / 1000 : null,
45
+ created_at: row.createdAt ? row.createdAt.getTime() / 1000 : null,
43
46
  worker_type: row.workerType,
44
47
  channel_group_id: row.bridgeId,
45
48
  capabilities: row.capabilities,
46
49
  team_id: row.teamId ?? null,
47
50
  team_name: row.teamName ?? null,
48
51
  owner_user_id: row.ownerUserId ?? null,
52
+ // Attribution: prefer the owning account's username; fall back to the
53
+ // OS user the worker reported at registration.
54
+ owner_username: row.ownerUsername ?? row.username ?? null,
49
55
  attach_waiting:
50
56
  row.sessionMode === 'attach' &&
51
57
  !storeListSessionsByEnvironment(row.id).some(
@@ -69,6 +75,7 @@ export function registerEnvironment(
69
75
  environment_id?: string
70
76
  metadata?: { worker_type?: string }
71
77
  username?: string
78
+ ipAddress?: string | null
72
79
  ownerUserId?: string | null
73
80
  teamId?: string | null
74
81
  claimToken?: string | null
@@ -97,6 +104,9 @@ export function registerEnvironment(
97
104
  machineName: req.machine_name,
98
105
  maxSessions: req.max_sessions,
99
106
  capabilities: req.capabilities ?? null,
107
+ // Refresh the peer address on every re-registration — a laptop that
108
+ // hopped networks should report its new address, not a stale one.
109
+ ...(req.ipAddress ? { ipAddress: req.ipAddress } : {}),
100
110
  sessionMode,
101
111
  })
102
112
  // Ownership is backfill-only: a restart must not reassign the env
@@ -158,6 +168,7 @@ export function registerEnvironment(
158
168
  capabilities: req.capabilities ?? null,
159
169
  machineName: req.machine_name,
160
170
  maxSessions: req.max_sessions,
171
+ ...(req.ipAddress ? { ipAddress: req.ipAddress } : {}),
161
172
  })
162
173
  // Backfill ownership: the reused env may still be unowned (claim flow
163
174
  // pending). Idempotent — storeClaimEnvironment only writes when
@@ -210,6 +221,7 @@ export function registerEnvironment(
210
221
  workerType,
211
222
  bridgeId: req.bridge_id,
212
223
  username: req.username,
224
+ ipAddress: req.ipAddress ?? undefined,
213
225
  capabilities: req.capabilities,
214
226
  ownerUserId: req.ownerUserId,
215
227
  claimToken: req.claimToken,
@@ -21,6 +21,14 @@ export interface EnvironmentRecord {
21
21
  capabilities: Record<string, unknown> | null
22
22
  status: string
23
23
  username: string | null
24
+ /**
25
+ * Peer address the worker registered from (captured at POST
26
+ * /v1/environments/bridge). In-memory only — like maxSessions/bridgeId the
27
+ * environments table has no column for it, and workers re-register with a
28
+ * fresh address on every restart. Null when the runtime couldn't resolve a
29
+ * peer address (e.g. a WS-only ACP path); the Web UI simply omits it.
30
+ */
31
+ ipAddress: string | null
24
32
  lastPollAt: Date | null
25
33
  createdAt: Date
26
34
  updatedAt: Date
@@ -123,6 +131,7 @@ export function storeCreateEnvironment(req: {
123
131
  workerType?: string
124
132
  bridgeId?: string
125
133
  username?: string
134
+ ipAddress?: string
126
135
  capabilities?: Record<string, unknown>
127
136
  ownerUserId?: string | null
128
137
  claimToken?: string | null
@@ -144,6 +153,7 @@ export function storeCreateEnvironment(req: {
144
153
  capabilities: req.capabilities ?? null,
145
154
  status: 'active',
146
155
  username: req.username ?? null,
156
+ ipAddress: req.ipAddress ?? null,
147
157
  lastPollAt: now,
148
158
  createdAt: now,
149
159
  updatedAt: now,
@@ -192,6 +202,7 @@ export function storeUpdateEnvironment(
192
202
  | 'machineName'
193
203
  | 'maxSessions'
194
204
  | 'bridgeId'
205
+ | 'ipAddress'
195
206
  | 'sessionMode'
196
207
  >
197
208
  >,
@@ -221,8 +232,8 @@ export function storeUpdateEnvironment(
221
232
  params.$sessionMode = patch.sessionMode
222
233
  }
223
234
 
224
- // bridgeId, maxSessions, capabilities, updatedAt are in-memory only —
225
- // the environments table has no corresponding columns.
235
+ // bridgeId, maxSessions, capabilities, ipAddress, updatedAt are
236
+ // in-memory only — the environments table has no corresponding columns.
226
237
 
227
238
  if (sets.length > 0) {
228
239
  db.query(`UPDATE environments SET ${sets.join(', ')} WHERE id = $id`).run(
@@ -249,6 +260,7 @@ export function storeListActiveEnvironmentsWithTeam(): Array<
249
260
  teamId: string | null
250
261
  teamName: string | null
251
262
  ownerUserId: string | null
263
+ ownerUsername: string | null
252
264
  }
253
265
  > {
254
266
  const active = [...environments.values()].filter(e => e.status === 'active')
@@ -256,8 +268,13 @@ export function storeListActiveEnvironmentsWithTeam(): Array<
256
268
 
257
269
  // Build a map of env_id → { teamId, teamName } from SQLite
258
270
  const teamMap = new Map<string, { teamId: string; teamName: string }>()
259
- // Build a map of env_id → ownerUserId from SQLite
260
- const ownerMap = new Map<string, string | null>()
271
+ // Build a map of env_id → { ownerUserId, ownerUsername } from SQLite.
272
+ // The username is joined here (rather than in the response layer) so the
273
+ // Web UI can attribute an environment to a human without a second query.
274
+ const ownerMap = new Map<
275
+ string,
276
+ { userId: string; username: string | null }
277
+ >()
261
278
  try {
262
279
  const db = getDb()
263
280
  const rows = db
@@ -279,11 +296,21 @@ export function storeListActiveEnvironmentsWithTeam(): Array<
279
296
  }
280
297
  const ownerRows = db
281
298
  .query(
282
- `SELECT id, owner_user_id FROM environments WHERE owner_user_id IS NOT NULL`,
299
+ `SELECT e.id, e.owner_user_id, u.username AS owner_username
300
+ FROM environments e
301
+ LEFT JOIN users u ON u.id = e.owner_user_id
302
+ WHERE e.owner_user_id IS NOT NULL`,
283
303
  )
284
- .all() as Array<{ id: string; owner_user_id: string }>
304
+ .all() as Array<{
305
+ id: string
306
+ owner_user_id: string
307
+ owner_username: string | null
308
+ }>
285
309
  for (const row of ownerRows) {
286
- ownerMap.set(row.id, row.owner_user_id)
310
+ ownerMap.set(row.id, {
311
+ userId: row.owner_user_id,
312
+ username: row.owner_username,
313
+ })
287
314
  }
288
315
  } catch (err) {
289
316
  console.error(
@@ -295,11 +322,13 @@ export function storeListActiveEnvironmentsWithTeam(): Array<
295
322
 
296
323
  return active.map(env => {
297
324
  const team = teamMap.get(env.id)
325
+ const owner = ownerMap.get(env.id)
298
326
  return {
299
327
  ...env,
300
328
  teamId: team?.teamId ?? null,
301
329
  teamName: team?.teamName ?? null,
302
- ownerUserId: ownerMap.get(env.id) ?? null,
330
+ ownerUserId: owner?.userId ?? null,
331
+ ownerUsername: owner?.username ?? null,
303
332
  }
304
333
  })
305
334
  }
@@ -135,13 +135,20 @@ export interface EnvironmentResponse {
135
135
  branch: string | null
136
136
  status: string
137
137
  username: string | null
138
+ /** Peer address the worker registered from. Null when unresolvable. */
139
+ ip_address: string | null
138
140
  last_poll_at: number | null
141
+ /** Unix seconds when the machine first registered (stable across restarts
142
+ * within a server lifetime). Null only for legacy rows. */
143
+ created_at: number | null
139
144
  worker_type?: string
140
145
  channel_group_id?: string | null
141
146
  capabilities?: Record<string, unknown> | null
142
147
  team_id: string | null
143
148
  team_name: string | null
144
149
  owner_user_id: string | null
150
+ /** Resolved username of the owning user (null if unowned/unresolvable). */
151
+ owner_username?: string | null
145
152
  /** Session Attach wait mode: registered to be assigned a session, none bound yet. */
146
153
  attach_waiting?: boolean
147
154
  }
@@ -0,0 +1 @@
1
+ import{e as d,j as e}from"./vendor-DE_-CLIE.js";import{aL as x,aM as o,a3 as m,aD as s,at as l,I as u}from"./main-BC4mcO_f.js";import"./preload-helper-BiaRt2Oj.js";import"./motion-BILbV7YQ.js";function j(){x();const[a,i]=d.useState([]),{myTeams:r,isLoading:c}=o(),n=d.useCallback(async()=>{try{const t=await m();i(t||[])}catch(t){console.error("Admin: failed to load sessions",t)}},[]);return d.useEffect(()=>{n()},[n]),e.jsx("div",{className:"flex-1 overflow-y-auto",children:e.jsxs("div",{className:"mx-auto max-w-5xl px-4 py-8",children:[e.jsx("h1",{className:"mb-6 font-display text-2xl font-semibold text-text-primary",children:s("admin.title")}),e.jsxs("section",{className:"mb-10",children:[e.jsxs("h2",{className:"mb-4 font-display text-lg font-semibold text-text-primary",children:[s("admin.teams")," (",r.length,")"]}),c?e.jsx("div",{className:"rounded-xl border border-border bg-surface-1 p-4 text-center text-text-muted",children:s("common.loading")}):r.length===0?e.jsx("div",{className:"rounded-xl border border-border bg-surface-1 p-4 text-center text-text-muted",children:s("admin.noTeams")}):e.jsx("div",{className:"space-y-2",children:r.map(t=>e.jsxs("a",{href:`/teams/${t.slug}`,className:"flex items-center justify-between rounded-xl border border-border bg-surface-1 px-4 py-3 no-underline transition-colors hover:border-border-light hover:bg-surface-2",children:[e.jsxs("div",{className:"min-w-0",children:[e.jsx("span",{className:"font-medium text-text-primary",children:t.name}),e.jsx("span",{className:"ml-2 text-xs text-text-muted",children:t.slug})]}),e.jsx("span",{className:"text-xs text-text-muted",children:l(new Date(t.created_at).getTime()/1e3)})]},t.id))})]}),e.jsxs("section",{children:[e.jsxs("h2",{className:"mb-4 font-display text-lg font-semibold text-text-primary",children:[s("admin.sessions")," (",a.length,")"]}),a.length===0?e.jsx("div",{className:"rounded-xl border border-border bg-surface-1 p-4 text-center text-text-muted",children:s("admin.noSessions")}):e.jsx("div",{className:"space-y-2",children:a.map(t=>e.jsxs("a",{href:`/code/${t.id}`,className:"flex items-center justify-between rounded-xl border border-border bg-surface-1 px-4 py-3 no-underline transition-colors hover:border-border-light hover:bg-surface-2",children:[e.jsxs("div",{className:"min-w-0 flex-1",children:[e.jsxs("div",{className:"flex items-center gap-2",children:[e.jsx("span",{className:"truncate font-medium text-text-primary",children:t.title||t.id}),e.jsx("span",{className:"rounded-full bg-surface-2 px-2 py-0.5 text-xs text-text-muted",children:t.source||"unknown"})]}),e.jsx("div",{className:"truncate text-xs text-text-muted",children:t.id})]}),e.jsxs("div",{className:"ml-4 flex items-center gap-3",children:[e.jsx(u,{status:t.status}),e.jsx("span",{className:"text-xs text-text-muted",children:l(t.updated_at||t.created_at)})]})]},t.id))})]})]})})}export{j as AdminPanel};
@@ -0,0 +1 @@
1
+ import{e as a,j as t}from"./vendor-DE_-CLIE.js";import{aL as A,a4 as j,aD as r,a1 as q,ao as R,P as U,N as F}from"./main-BC4mcO_f.js";import{S as O,E as G,C as K}from"./ArtifactsGallery-CcobkOm1.js";import{R as P}from"./refresh-cw-DBXI7gD3.js";import{C as J}from"./copy-EPASKX-X.js";import"./preload-helper-BiaRt2Oj.js";import"./motion-BILbV7YQ.js";import"./dialog-Ort95zkZ.js";let m=null;function M(n,c,e=0){b();const o=`/web/sessions/${n}/events`,l=new EventSource(o,{withCredentials:!0});m=l;let u=e;l.addEventListener("message",p=>{try{const x=JSON.parse(p.data);if(x.seqNum!==void 0&&x.seqNum<=u)return;x.seqNum!==void 0&&(u=x.seqNum),c(x)}catch{}}),l.addEventListener("error",()=>{console.warn("[SSE] error, readyState:",l.readyState),l.readyState===EventSource.CLOSED&&(l.close(),b())})}function b(){m&&(m.close(),m=null)}function V(n,c){const e=a.useRef(c);e.current=c;const o=a.useCallback(l=>{e.current(l)},[]);a.useEffect(()=>{if(n)return M(n,o),()=>{b()}},[n,o])}function I({artifactId:n,onBack:c}){A();const[e,o]=a.useState(null),[l,u]=a.useState(""),[p,x]=a.useState(!1),[S,f]=a.useState(0),[w,h]=a.useState(!1),[g,C]=a.useState(null),[E,k]=a.useState("template"),[d,y]=a.useState(!1);a.useEffect(()=>{let s=!1;return j(n).then(i=>{s||o(i)}).catch(i=>{s||u(i instanceof Error?i.message:r("artifacts.viewNotFound"))}),()=>{s=!0}},[n]);const v=a.useCallback(()=>{j(n).then(s=>o(s)).catch(()=>{})},[n]),_=a.useCallback(s=>{var i;s.type==="artifact_updated"&&((i=s.payload)!=null&&i.id&&s.payload.id!==n||(v(),f(D=>D+1),y(!0)))},[n,v]);V((e==null?void 0:e.session_id)??null,_),a.useEffect(()=>{if(!d)return;const s=setTimeout(()=>y(!1),2500);return()=>clearTimeout(s)},[d]);const N=a.useCallback(s=>{e&&(C(e),k(s),h(!0))},[e]),$=a.useCallback(s=>{h(!1),o(i=>i?{...i,...s}:s),f(i=>i+1)},[]),T=a.useCallback(async()=>{if(window.confirm(r("artifacts.delete")+" — "+n.slice(0,8)+"…?"))try{await q(n),c()}catch(s){alert(s instanceof Error?s.message:r("artifacts.deleteFailed"))}},[n,c]),L=a.useCallback(async()=>{if(!e)return;await R(`${window.location.origin}${e.url}`)&&(x(!0),setTimeout(()=>x(!1),1500))},[e]);return l?t.jsx("div",{className:"flex flex-1 items-center justify-center",children:t.jsxs("div",{className:"text-center",children:[t.jsx("p",{className:"text-status-error",children:r("artifacts.viewNotFound")}),t.jsx("p",{className:"mt-1 text-xs text-text-muted",children:l}),t.jsx("button",{type:"button",onClick:c,className:"mt-4 rounded-md border border-border px-4 py-2 text-sm text-text-secondary hover:bg-surface-2",children:r("artifacts.backToGallery")})]})}):e?t.jsxs("div",{className:"flex h-full min-h-0 flex-col",children:[t.jsxs("div",{className:"flex flex-wrap items-center gap-2 border-b border-border bg-surface-1 px-4 py-2.5",children:[t.jsx("button",{type:"button",onClick:c,className:"text-sm text-text-muted hover:text-text-primary",children:r("artifacts.backToGallery")}),t.jsx("span",{className:"text-text-muted/40",children:"/"}),t.jsx("span",{className:"truncate font-medium text-text-primary",children:e.title||e.id.slice(0,12)}),t.jsx("span",{className:`rounded-full px-2 py-0.5 text-[10px] transition-colors ${d?"bg-status-active/15 text-status-active":"bg-surface-3 text-text-muted"}`,title:d?r("artifacts.view.liveUpdated"):void 0,children:d?`↻ v${e.version}`:`v${e.version}`}),e.session_id&&t.jsxs("a",{href:`/code/${e.session_id}`,className:"truncate font-mono text-[10px] text-text-muted hover:text-accent",title:e.session_id,children:[r("artifacts.session"),": ",e.session_id.slice(0,14),"…"]}),e.expires_at&&t.jsxs("span",{className:"text-[10px] text-text-muted",title:e.expires_at,children:[r("artifacts.expires"),": ",new Date(e.expires_at).toLocaleDateString()]}),t.jsxs("div",{className:"ml-auto flex items-center gap-1",children:[t.jsx("button",{type:"button",onClick:()=>f(s=>s+1),className:"inline-flex items-center gap-1 rounded-md px-2 py-1 text-xs text-text-secondary hover:bg-surface-2 hover:text-text-primary",title:r("common.loading"),children:t.jsx(P,{className:"h-3.5 w-3.5"})}),t.jsx("button",{type:"button",onClick:()=>N("ai"),className:"inline-flex items-center gap-1 rounded-md px-2 py-1 text-xs text-text-secondary hover:bg-surface-2 hover:text-text-primary",title:r("artifacts.aiUpdate"),children:t.jsx(O,{className:"h-3.5 w-3.5"})}),e.can_manage&&t.jsx("button",{type:"button",onClick:()=>N("template"),className:"inline-flex items-center gap-1 rounded-md px-2 py-1 text-xs text-text-secondary hover:bg-surface-2 hover:text-text-primary",title:r("artifacts.edit"),children:t.jsx(U,{className:"h-3.5 w-3.5"})}),t.jsxs("button",{type:"button",onClick:L,className:"inline-flex items-center gap-1 rounded-md px-2 py-1 text-xs text-text-secondary hover:bg-surface-2 hover:text-text-primary",title:`${r("artifacts.copyLink")} · ${r("artifacts.linkNotice")}`,children:[t.jsx(J,{className:"h-3.5 w-3.5"}),p&&t.jsx("span",{className:"text-status-active",children:r("artifacts.copied")})]}),t.jsx("a",{href:e.url,target:"_blank",rel:"noreferrer",className:"inline-flex items-center gap-1 rounded-md px-2 py-1 text-xs text-text-secondary hover:bg-surface-2 hover:text-text-primary",title:r("artifacts.openInNewTab"),children:t.jsx(G,{className:"h-3.5 w-3.5"})}),t.jsx("button",{type:"button",onClick:T,className:"inline-flex items-center gap-1 rounded-md px-2 py-1 text-xs text-text-secondary hover:bg-status-error/10 hover:text-status-error",title:r("artifacts.delete"),children:t.jsx(F,{className:"h-3.5 w-3.5"})})]})]}),t.jsx("iframe",{src:`${e.url}${e.url.includes("?")?"&":"?"}_=${Date.now()}`,title:e.title||e.id,className:"min-h-0 w-full flex-1 border-0 bg-white",sandbox:"allow-scripts allow-popups allow-forms"},S),t.jsx(K,{open:w,onClose:()=>h(!1),onCreated:$,editArtifact:g,initialMode:E})]}):t.jsx("div",{className:"flex flex-1 items-center justify-center text-text-muted",children:r("common.loading")})}export{I as ArtifactView};