@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.
- package/dist/cli.js +444 -327
- package/dist/guide/guide-data.json +174 -174
- package/dist/rcs-web/assets/AdminPanel-D0fVkpU2.js +1 -0
- package/dist/rcs-web/assets/ArtifactView-DG0-kZ2G.js +1 -0
- package/{packages/remote-control-server/web/dist/assets/ArtifactsGallery-B63LTThv.js → dist/rcs-web/assets/ArtifactsGallery-CcobkOm1.js} +31 -31
- package/dist/rcs-web/assets/Claim-CltNvmRS.js +1 -0
- package/dist/rcs-web/assets/Dashboard-CEzuQ0N4.js +6 -0
- package/dist/rcs-web/assets/Join-DX0LzcPE.js +1 -0
- package/dist/rcs-web/assets/Login-BVKB4X_Z.js +1 -0
- package/dist/rcs-web/assets/Register-D-BrLVl3.js +1 -0
- package/dist/rcs-web/assets/RegisterEmpty-DdDXaiEn.js +26 -0
- package/dist/rcs-web/assets/SessionDetail-BkKSNMD8.js +78 -0
- package/dist/rcs-web/assets/{SessionVisibilityBadge-DA_Sg1dx.js → SessionVisibilityBadge-Ch3s2iFY.js} +2 -2
- package/dist/rcs-web/assets/Setup-CyGhRI5L.js +1 -0
- package/dist/rcs-web/assets/{ShareLanding-DaLDc5iV.js → ShareLanding-xKcBqmJb.js} +1 -1
- package/dist/rcs-web/assets/TeamDetail-C3Ne25hE.js +11 -0
- package/dist/rcs-web/assets/TeamList-C5Zyrj2-.js +1 -0
- package/dist/rcs-web/assets/TeamSettings-BsT93PQO.js +1 -0
- package/dist/rcs-web/assets/UserSearchInput-BFpwaVmp.js +6 -0
- package/dist/rcs-web/assets/UserSettings-cIzS243Z.js +1 -0
- package/dist/rcs-web/assets/{arc-CPhgreP8.js → arc-CiWQl09E.js} +1 -1
- package/dist/rcs-web/assets/{architectureDiagram-3BPJPVTR-CpAi-qzk.js → architectureDiagram-3BPJPVTR-DL5Id6fa.js} +1 -1
- package/{packages/remote-control-server/web/dist/assets/blockDiagram-GPEHLZMM-DcsxgO1K.js → dist/rcs-web/assets/blockDiagram-GPEHLZMM-DF-nk9Fe.js} +1 -1
- package/{packages/remote-control-server/web/dist/assets/c4Diagram-AAUBKEIU-BQ5cjzbZ.js → dist/rcs-web/assets/c4Diagram-AAUBKEIU-l_Pl6m2J.js} +1 -1
- package/dist/rcs-web/assets/channel-CBq46cRr.js +1 -0
- package/dist/rcs-web/assets/{chunk-2J33WTMH-wa-oCiR6.js → chunk-2J33WTMH-Dr5xQSXu.js} +1 -1
- package/dist/rcs-web/assets/{chunk-4BX2VUAB-D2ybEyPG.js → chunk-4BX2VUAB-DAPTU1FG.js} +1 -1
- package/dist/rcs-web/assets/{chunk-55IACEB6-CQGtwyGQ.js → chunk-55IACEB6-BgaGrvZR.js} +1 -1
- package/{packages/remote-control-server/web/dist/assets/chunk-727SXJPM-D0ITaMeP.js → dist/rcs-web/assets/chunk-727SXJPM-D6dnSxU3.js} +1 -1
- package/{packages/remote-control-server/web/dist/assets/chunk-AQP2D5EJ-BWRrcP1d.js → dist/rcs-web/assets/chunk-AQP2D5EJ-BVCad_JN.js} +1 -1
- package/dist/rcs-web/assets/{chunk-FMBD7UC4-C-CaLwfI.js → chunk-FMBD7UC4-BNLx608W.js} +1 -1
- package/dist/rcs-web/assets/{chunk-ND2GUHAM-OPpmIsi8.js → chunk-ND2GUHAM-BAHk1eiL.js} +1 -1
- package/dist/rcs-web/assets/{chunk-QZHKN3VN-Bq6R2yM7.js → chunk-QZHKN3VN-CX_4LT0M.js} +1 -1
- package/dist/rcs-web/assets/classDiagram-4FO5ZUOK-CYdZp3iH.js +1 -0
- package/dist/rcs-web/assets/classDiagram-v2-Q7XG4LA2-CYdZp3iH.js +1 -0
- 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
- package/dist/rcs-web/assets/{copy-lzYYFmlH.js → copy-EPASKX-X.js} +1 -1
- package/{packages/remote-control-server/web/dist/assets/cose-bilkent-S5V4N54A-CuUSRgoZ.js → dist/rcs-web/assets/cose-bilkent-S5V4N54A-CMpuIlrx.js} +1 -1
- package/{packages/remote-control-server/web/dist/assets/dagre-BM42HDAG-BP4ZP_3D.js → dist/rcs-web/assets/dagre-BM42HDAG-Dg4Q9j21.js} +1 -1
- package/dist/rcs-web/assets/{diagram-2AECGRRQ-XQnH0b9k.js → diagram-2AECGRRQ-YGGSegJh.js} +1 -1
- package/dist/rcs-web/assets/{diagram-5GNKFQAL-BnuYmMPD.js → diagram-5GNKFQAL-Rg7tQ7zl.js} +1 -1
- package/{packages/remote-control-server/web/dist/assets/diagram-KO2AKTUF-LymV4oAW.js → dist/rcs-web/assets/diagram-KO2AKTUF-FwQUsRJf.js} +1 -1
- package/dist/rcs-web/assets/{diagram-LMA3HP47-NSg5NWFp.js → diagram-LMA3HP47-DDzZwu_E.js} +1 -1
- package/dist/rcs-web/assets/{diagram-OG6HWLK6-kVTMFgtZ.js → diagram-OG6HWLK6-D6Pxp9XO.js} +1 -1
- package/dist/rcs-web/assets/dialog-Ort95zkZ.js +1 -0
- package/dist/rcs-web/assets/{erDiagram-TEJ5UH35-BJBTtX2s.js → erDiagram-TEJ5UH35-BSDAq23h.js} +1 -1
- package/dist/rcs-web/assets/{flowDiagram-I6XJVG4X-CcQXZNID.js → flowDiagram-I6XJVG4X-CzWT0vwA.js} +1 -1
- package/{packages/remote-control-server/web/dist/assets/ganttDiagram-6RSMTGT7-DW8iKyq_.js → dist/rcs-web/assets/ganttDiagram-6RSMTGT7-DPNJQ_Co.js} +1 -1
- package/{packages/remote-control-server/web/dist/assets/gitGraphDiagram-PVQCEYII-BTBYx3LF.js → dist/rcs-web/assets/gitGraphDiagram-PVQCEYII-vHpFxzAD.js} +1 -1
- package/dist/rcs-web/assets/{infoDiagram-5YYISTIA-BRZAYc6t.js → infoDiagram-5YYISTIA-Bk_F8hwq.js} +1 -1
- package/{packages/remote-control-server/web/dist/assets/ishikawaDiagram-YF4QCWOH-BYMQtEeD.js → dist/rcs-web/assets/ishikawaDiagram-YF4QCWOH-CBYfpD17.js} +1 -1
- package/{packages/remote-control-server/web/dist/assets/journeyDiagram-JHISSGLW-aqx7w1db.js → dist/rcs-web/assets/journeyDiagram-JHISSGLW-BxoYxLNN.js} +1 -1
- package/{packages/remote-control-server/web/dist/assets/kanban-definition-UN3LZRKU-BxEHfP4O.js → dist/rcs-web/assets/kanban-definition-UN3LZRKU-B5pCpO1z.js} +1 -1
- package/dist/rcs-web/assets/{linear-Chjw8hPE.js → linear-BpcrEfNA.js} +1 -1
- package/dist/rcs-web/assets/main-BC4mcO_f.js +393 -0
- package/dist/rcs-web/assets/main-C0n90aVY.css +1 -0
- package/{packages/remote-control-server/web/dist/assets/mermaid-VLURNSYL-CrqI4db6.js → dist/rcs-web/assets/mermaid-VLURNSYL-DWwqH0oB.js} +4 -4
- package/dist/rcs-web/assets/{mermaid.core-EjsI3GC3.js → mermaid.core-CPGFiRhL.js} +5 -5
- package/dist/rcs-web/assets/{mindmap-definition-RKZ34NQL-D2rO_fGA.js → mindmap-definition-RKZ34NQL-DBF7JLl0.js} +1 -1
- package/dist/rcs-web/assets/{notifications-WMIbgYDP.js → notifications-C7DetfWu.js} +1 -1
- package/dist/rcs-web/assets/{pieDiagram-4H26LBE5-DDwJZfoh.js → pieDiagram-4H26LBE5-CbUgqUZY.js} +1 -1
- package/dist/rcs-web/assets/{quadrantDiagram-W4KKPZXB-DDtqMwKx.js → quadrantDiagram-W4KKPZXB-BUF-YWIU.js} +1 -1
- package/dist/rcs-web/assets/{refresh-cw-l0u8pxJi.js → refresh-cw-DBXI7gD3.js} +1 -1
- package/{packages/remote-control-server/web/dist/assets/requirementDiagram-4Y6WPE33-BtSk2-5u.js → dist/rcs-web/assets/requirementDiagram-4Y6WPE33-B8fyHxTP.js} +1 -1
- package/dist/rcs-web/assets/{sankeyDiagram-5OEKKPKP-SDLDMxUT.js → sankeyDiagram-5OEKKPKP-DAZKpwBw.js} +1 -1
- package/dist/rcs-web/assets/{sequenceDiagram-3UESZ5HK-D7iAclg1.js → sequenceDiagram-3UESZ5HK-DamEgVx-.js} +1 -1
- package/dist/rcs-web/assets/{stateDiagram-AJRCARHV-Bxx23fZH.js → stateDiagram-AJRCARHV-DU-QvteV.js} +1 -1
- package/dist/rcs-web/assets/{stateDiagram-v2-BHNVJYJU-z1g82auz.js → stateDiagram-v2-BHNVJYJU-C5QVbdY9.js} +1 -1
- package/dist/rcs-web/assets/{timeline-definition-PNZ67QCA-C8kBbm_V.js → timeline-definition-PNZ67QCA-Df0hGAH6.js} +1 -1
- package/dist/rcs-web/assets/{vennDiagram-CIIHVFJN-CPldb1-R.js → vennDiagram-CIIHVFJN-DbX36wdR.js} +1 -1
- package/{packages/remote-control-server/web/dist/assets/wardleyDiagram-YWT4CUSO-MCHB2fG7.js → dist/rcs-web/assets/wardleyDiagram-YWT4CUSO-rjVkCTKo.js} +1 -1
- package/dist/rcs-web/assets/workerType-gCLCeJDi.js +6 -0
- package/dist/rcs-web/assets/{xychartDiagram-2RQKCTM6-CHj-KmL6.js → xychartDiagram-2RQKCTM6-CHjulBZn.js} +1 -1
- package/dist/rcs-web/index.html +2 -2
- package/package.json +2 -1
- package/packages/remote-control-server/src/__tests__/backgroundTaskPipeline.test.ts +216 -0
- package/packages/remote-control-server/src/__tests__/client-ip.test.ts +67 -0
- package/packages/remote-control-server/src/__tests__/teams.test.ts +44 -0
- package/packages/remote-control-server/src/client-ip.ts +57 -0
- package/packages/remote-control-server/src/db/sqlite.ts +22 -0
- package/packages/remote-control-server/src/routes/v1/environments.ts +4 -0
- package/packages/remote-control-server/src/routes/web/teams.ts +12 -1
- package/packages/remote-control-server/src/services/environment.ts +12 -0
- package/packages/remote-control-server/src/store.ts +37 -8
- package/packages/remote-control-server/src/types/api.ts +7 -0
- package/packages/remote-control-server/web/dist/assets/AdminPanel-D0fVkpU2.js +1 -0
- package/packages/remote-control-server/web/dist/assets/ArtifactView-DG0-kZ2G.js +1 -0
- package/{dist/rcs-web/assets/ArtifactsGallery-B63LTThv.js → packages/remote-control-server/web/dist/assets/ArtifactsGallery-CcobkOm1.js} +31 -31
- package/packages/remote-control-server/web/dist/assets/Claim-CltNvmRS.js +1 -0
- package/packages/remote-control-server/web/dist/assets/Dashboard-CEzuQ0N4.js +6 -0
- package/packages/remote-control-server/web/dist/assets/Join-DX0LzcPE.js +1 -0
- package/packages/remote-control-server/web/dist/assets/Login-BVKB4X_Z.js +1 -0
- package/packages/remote-control-server/web/dist/assets/Register-D-BrLVl3.js +1 -0
- package/packages/remote-control-server/web/dist/assets/RegisterEmpty-DdDXaiEn.js +26 -0
- package/packages/remote-control-server/web/dist/assets/SessionDetail-BkKSNMD8.js +78 -0
- package/packages/remote-control-server/web/dist/assets/{SessionVisibilityBadge-DA_Sg1dx.js → SessionVisibilityBadge-Ch3s2iFY.js} +2 -2
- package/packages/remote-control-server/web/dist/assets/Setup-CyGhRI5L.js +1 -0
- package/packages/remote-control-server/web/dist/assets/{ShareLanding-DaLDc5iV.js → ShareLanding-xKcBqmJb.js} +1 -1
- package/packages/remote-control-server/web/dist/assets/TeamDetail-C3Ne25hE.js +11 -0
- package/packages/remote-control-server/web/dist/assets/TeamList-C5Zyrj2-.js +1 -0
- package/packages/remote-control-server/web/dist/assets/TeamSettings-BsT93PQO.js +1 -0
- package/packages/remote-control-server/web/dist/assets/UserSearchInput-BFpwaVmp.js +6 -0
- package/packages/remote-control-server/web/dist/assets/UserSettings-cIzS243Z.js +1 -0
- package/packages/remote-control-server/web/dist/assets/{arc-CPhgreP8.js → arc-CiWQl09E.js} +1 -1
- package/packages/remote-control-server/web/dist/assets/{architectureDiagram-3BPJPVTR-CpAi-qzk.js → architectureDiagram-3BPJPVTR-DL5Id6fa.js} +1 -1
- package/{dist/rcs-web/assets/blockDiagram-GPEHLZMM-DcsxgO1K.js → packages/remote-control-server/web/dist/assets/blockDiagram-GPEHLZMM-DF-nk9Fe.js} +1 -1
- package/{dist/rcs-web/assets/c4Diagram-AAUBKEIU-BQ5cjzbZ.js → packages/remote-control-server/web/dist/assets/c4Diagram-AAUBKEIU-l_Pl6m2J.js} +1 -1
- package/packages/remote-control-server/web/dist/assets/channel-CBq46cRr.js +1 -0
- package/packages/remote-control-server/web/dist/assets/{chunk-2J33WTMH-wa-oCiR6.js → chunk-2J33WTMH-Dr5xQSXu.js} +1 -1
- package/packages/remote-control-server/web/dist/assets/{chunk-4BX2VUAB-D2ybEyPG.js → chunk-4BX2VUAB-DAPTU1FG.js} +1 -1
- package/packages/remote-control-server/web/dist/assets/{chunk-55IACEB6-CQGtwyGQ.js → chunk-55IACEB6-BgaGrvZR.js} +1 -1
- package/{dist/rcs-web/assets/chunk-727SXJPM-D0ITaMeP.js → packages/remote-control-server/web/dist/assets/chunk-727SXJPM-D6dnSxU3.js} +1 -1
- package/{dist/rcs-web/assets/chunk-AQP2D5EJ-BWRrcP1d.js → packages/remote-control-server/web/dist/assets/chunk-AQP2D5EJ-BVCad_JN.js} +1 -1
- package/packages/remote-control-server/web/dist/assets/{chunk-FMBD7UC4-C-CaLwfI.js → chunk-FMBD7UC4-BNLx608W.js} +1 -1
- package/packages/remote-control-server/web/dist/assets/{chunk-ND2GUHAM-OPpmIsi8.js → chunk-ND2GUHAM-BAHk1eiL.js} +1 -1
- package/packages/remote-control-server/web/dist/assets/{chunk-QZHKN3VN-Bq6R2yM7.js → chunk-QZHKN3VN-CX_4LT0M.js} +1 -1
- package/packages/remote-control-server/web/dist/assets/classDiagram-4FO5ZUOK-CYdZp3iH.js +1 -0
- package/packages/remote-control-server/web/dist/assets/classDiagram-v2-Q7XG4LA2-CYdZp3iH.js +1 -0
- 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
- package/packages/remote-control-server/web/dist/assets/{copy-lzYYFmlH.js → copy-EPASKX-X.js} +1 -1
- package/{dist/rcs-web/assets/cose-bilkent-S5V4N54A-CuUSRgoZ.js → packages/remote-control-server/web/dist/assets/cose-bilkent-S5V4N54A-CMpuIlrx.js} +1 -1
- package/{dist/rcs-web/assets/dagre-BM42HDAG-BP4ZP_3D.js → packages/remote-control-server/web/dist/assets/dagre-BM42HDAG-Dg4Q9j21.js} +1 -1
- package/packages/remote-control-server/web/dist/assets/{diagram-2AECGRRQ-XQnH0b9k.js → diagram-2AECGRRQ-YGGSegJh.js} +1 -1
- package/packages/remote-control-server/web/dist/assets/{diagram-5GNKFQAL-BnuYmMPD.js → diagram-5GNKFQAL-Rg7tQ7zl.js} +1 -1
- package/{dist/rcs-web/assets/diagram-KO2AKTUF-LymV4oAW.js → packages/remote-control-server/web/dist/assets/diagram-KO2AKTUF-FwQUsRJf.js} +1 -1
- package/packages/remote-control-server/web/dist/assets/{diagram-LMA3HP47-NSg5NWFp.js → diagram-LMA3HP47-DDzZwu_E.js} +1 -1
- package/packages/remote-control-server/web/dist/assets/{diagram-OG6HWLK6-kVTMFgtZ.js → diagram-OG6HWLK6-D6Pxp9XO.js} +1 -1
- package/packages/remote-control-server/web/dist/assets/dialog-Ort95zkZ.js +1 -0
- package/packages/remote-control-server/web/dist/assets/{erDiagram-TEJ5UH35-BJBTtX2s.js → erDiagram-TEJ5UH35-BSDAq23h.js} +1 -1
- package/packages/remote-control-server/web/dist/assets/{flowDiagram-I6XJVG4X-CcQXZNID.js → flowDiagram-I6XJVG4X-CzWT0vwA.js} +1 -1
- package/{dist/rcs-web/assets/ganttDiagram-6RSMTGT7-DW8iKyq_.js → packages/remote-control-server/web/dist/assets/ganttDiagram-6RSMTGT7-DPNJQ_Co.js} +1 -1
- package/{dist/rcs-web/assets/gitGraphDiagram-PVQCEYII-BTBYx3LF.js → packages/remote-control-server/web/dist/assets/gitGraphDiagram-PVQCEYII-vHpFxzAD.js} +1 -1
- package/packages/remote-control-server/web/dist/assets/{infoDiagram-5YYISTIA-BRZAYc6t.js → infoDiagram-5YYISTIA-Bk_F8hwq.js} +1 -1
- package/{dist/rcs-web/assets/ishikawaDiagram-YF4QCWOH-BYMQtEeD.js → packages/remote-control-server/web/dist/assets/ishikawaDiagram-YF4QCWOH-CBYfpD17.js} +1 -1
- package/{dist/rcs-web/assets/journeyDiagram-JHISSGLW-aqx7w1db.js → packages/remote-control-server/web/dist/assets/journeyDiagram-JHISSGLW-BxoYxLNN.js} +1 -1
- package/{dist/rcs-web/assets/kanban-definition-UN3LZRKU-BxEHfP4O.js → packages/remote-control-server/web/dist/assets/kanban-definition-UN3LZRKU-B5pCpO1z.js} +1 -1
- package/packages/remote-control-server/web/dist/assets/{linear-Chjw8hPE.js → linear-BpcrEfNA.js} +1 -1
- package/packages/remote-control-server/web/dist/assets/main-BC4mcO_f.js +393 -0
- package/packages/remote-control-server/web/dist/assets/main-C0n90aVY.css +1 -0
- package/{dist/rcs-web/assets/mermaid-VLURNSYL-CrqI4db6.js → packages/remote-control-server/web/dist/assets/mermaid-VLURNSYL-DWwqH0oB.js} +4 -4
- package/packages/remote-control-server/web/dist/assets/{mermaid.core-EjsI3GC3.js → mermaid.core-CPGFiRhL.js} +5 -5
- package/packages/remote-control-server/web/dist/assets/{mindmap-definition-RKZ34NQL-D2rO_fGA.js → mindmap-definition-RKZ34NQL-DBF7JLl0.js} +1 -1
- package/packages/remote-control-server/web/dist/assets/{notifications-WMIbgYDP.js → notifications-C7DetfWu.js} +1 -1
- package/packages/remote-control-server/web/dist/assets/{pieDiagram-4H26LBE5-DDwJZfoh.js → pieDiagram-4H26LBE5-CbUgqUZY.js} +1 -1
- package/packages/remote-control-server/web/dist/assets/{quadrantDiagram-W4KKPZXB-DDtqMwKx.js → quadrantDiagram-W4KKPZXB-BUF-YWIU.js} +1 -1
- package/packages/remote-control-server/web/dist/assets/{refresh-cw-l0u8pxJi.js → refresh-cw-DBXI7gD3.js} +1 -1
- package/{dist/rcs-web/assets/requirementDiagram-4Y6WPE33-BtSk2-5u.js → packages/remote-control-server/web/dist/assets/requirementDiagram-4Y6WPE33-B8fyHxTP.js} +1 -1
- package/packages/remote-control-server/web/dist/assets/{sankeyDiagram-5OEKKPKP-SDLDMxUT.js → sankeyDiagram-5OEKKPKP-DAZKpwBw.js} +1 -1
- package/packages/remote-control-server/web/dist/assets/{sequenceDiagram-3UESZ5HK-D7iAclg1.js → sequenceDiagram-3UESZ5HK-DamEgVx-.js} +1 -1
- package/packages/remote-control-server/web/dist/assets/{stateDiagram-AJRCARHV-Bxx23fZH.js → stateDiagram-AJRCARHV-DU-QvteV.js} +1 -1
- package/packages/remote-control-server/web/dist/assets/{stateDiagram-v2-BHNVJYJU-z1g82auz.js → stateDiagram-v2-BHNVJYJU-C5QVbdY9.js} +1 -1
- package/packages/remote-control-server/web/dist/assets/{timeline-definition-PNZ67QCA-C8kBbm_V.js → timeline-definition-PNZ67QCA-Df0hGAH6.js} +1 -1
- package/packages/remote-control-server/web/dist/assets/{vennDiagram-CIIHVFJN-CPldb1-R.js → vennDiagram-CIIHVFJN-DbX36wdR.js} +1 -1
- package/{dist/rcs-web/assets/wardleyDiagram-YWT4CUSO-MCHB2fG7.js → packages/remote-control-server/web/dist/assets/wardleyDiagram-YWT4CUSO-rjVkCTKo.js} +1 -1
- package/packages/remote-control-server/web/dist/assets/workerType-gCLCeJDi.js +6 -0
- package/packages/remote-control-server/web/dist/assets/{xychartDiagram-2RQKCTM6-CHj-KmL6.js → xychartDiagram-2RQKCTM6-CHjulBZn.js} +1 -1
- package/packages/remote-control-server/web/dist/index.html +2 -2
- package/dist/rcs-web/assets/AdminPanel-fsacwgfK.js +0 -1
- package/dist/rcs-web/assets/ArtifactView-DmMwrTRk.js +0 -1
- package/dist/rcs-web/assets/Claim-hOGNTz-n.js +0 -1
- package/dist/rcs-web/assets/Dashboard-BBIlAMpr.js +0 -6
- package/dist/rcs-web/assets/Join-zelwrNDz.js +0 -1
- package/dist/rcs-web/assets/Login-BmYeCfbw.js +0 -1
- package/dist/rcs-web/assets/Register-Dfw4S_A0.js +0 -1
- package/dist/rcs-web/assets/SessionDetail-zXHv84SV.js +0 -83
- package/dist/rcs-web/assets/Setup-BTTET7Rk.js +0 -1
- package/dist/rcs-web/assets/TeamCreate-BWtaB-_Z.js +0 -1
- package/dist/rcs-web/assets/TeamDetail-Crmn6PaC.js +0 -6
- package/dist/rcs-web/assets/TeamList-B8Rob6VK.js +0 -1
- package/dist/rcs-web/assets/TeamSettings-CfRHolhe.js +0 -1
- package/dist/rcs-web/assets/UserSearchInput-DkaGgR76.js +0 -1
- package/dist/rcs-web/assets/UserSettings-D1oW7oVv.js +0 -1
- package/dist/rcs-web/assets/channel-DHj-rIRW.js +0 -1
- package/dist/rcs-web/assets/classDiagram-4FO5ZUOK-DsAw9J1B.js +0 -1
- package/dist/rcs-web/assets/classDiagram-v2-Q7XG4LA2-DsAw9J1B.js +0 -1
- package/dist/rcs-web/assets/dialog-DrDf89nL.js +0 -1
- package/dist/rcs-web/assets/main-CJvwpIVn.css +0 -1
- package/dist/rcs-web/assets/main-Dh-rPGBg.js +0 -275
- package/dist/rcs-web/assets/workerType-BOi1t0TG.js +0 -1
- package/packages/remote-control-server/web/dist/assets/AdminPanel-fsacwgfK.js +0 -1
- package/packages/remote-control-server/web/dist/assets/ArtifactView-DmMwrTRk.js +0 -1
- package/packages/remote-control-server/web/dist/assets/Claim-hOGNTz-n.js +0 -1
- package/packages/remote-control-server/web/dist/assets/Dashboard-BBIlAMpr.js +0 -6
- package/packages/remote-control-server/web/dist/assets/Join-zelwrNDz.js +0 -1
- package/packages/remote-control-server/web/dist/assets/Login-BmYeCfbw.js +0 -1
- package/packages/remote-control-server/web/dist/assets/Register-Dfw4S_A0.js +0 -1
- package/packages/remote-control-server/web/dist/assets/SessionDetail-zXHv84SV.js +0 -83
- package/packages/remote-control-server/web/dist/assets/Setup-BTTET7Rk.js +0 -1
- package/packages/remote-control-server/web/dist/assets/TeamCreate-BWtaB-_Z.js +0 -1
- package/packages/remote-control-server/web/dist/assets/TeamDetail-Crmn6PaC.js +0 -6
- package/packages/remote-control-server/web/dist/assets/TeamList-B8Rob6VK.js +0 -1
- package/packages/remote-control-server/web/dist/assets/TeamSettings-CfRHolhe.js +0 -1
- package/packages/remote-control-server/web/dist/assets/UserSearchInput-DkaGgR76.js +0 -1
- package/packages/remote-control-server/web/dist/assets/UserSettings-D1oW7oVv.js +0 -1
- package/packages/remote-control-server/web/dist/assets/channel-DHj-rIRW.js +0 -1
- package/packages/remote-control-server/web/dist/assets/classDiagram-4FO5ZUOK-DsAw9J1B.js +0 -1
- package/packages/remote-control-server/web/dist/assets/classDiagram-v2-Q7XG4LA2-DsAw9J1B.js +0 -1
- package/packages/remote-control-server/web/dist/assets/dialog-DrDf89nL.js +0 -1
- package/packages/remote-control-server/web/dist/assets/main-CJvwpIVn.css +0 -1
- package/packages/remote-control-server/web/dist/assets/main-Dh-rPGBg.js +0 -275
- 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
|
-
|
|
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
|
|
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
|
-
|
|
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
|
|
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<{
|
|
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,
|
|
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:
|
|
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};
|