@saluzi/saluzi-edu 0.2.65 → 0.2.67
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 +534 -349
- package/dist/guide/guide-data.json +8 -0
- package/dist/rcs-schema.sql +23 -0
- package/dist/rcs-web/assets/{AdminPanel-CqP_94xa.js → AdminPanel-94uchXH7.js} +1 -1
- package/dist/rcs-web/assets/ArtifactView-CT0Fu4U5.js +6 -0
- package/dist/rcs-web/assets/ArtifactsGallery-DgK1CSno.js +339 -0
- package/{packages/remote-control-server/web/dist/assets/Claim-BvfARQ6Q.js → dist/rcs-web/assets/Claim-C7V1Q01Y.js} +1 -1
- package/dist/rcs-web/assets/{Dashboard-BDGi4XpN.js → Dashboard-NLM7Kgm8.js} +2 -2
- package/{packages/remote-control-server/web/dist/assets/Join-PPDYBhsJ.js → dist/rcs-web/assets/Join-BhjsvbAP.js} +1 -1
- package/dist/rcs-web/assets/{Login-JprQIEpr.js → Login-DRFE4F-F.js} +1 -1
- package/dist/rcs-web/assets/{Register-cuGuAE83.js → Register-FgLOFB4h.js} +1 -1
- package/dist/rcs-web/assets/SessionDetail-3P77L-sJ.js +60 -0
- package/dist/rcs-web/assets/SessionVisibilityBadge-raEV1sW8.js +11 -0
- package/dist/rcs-web/assets/{Setup-Buwa9Y3M.js → Setup-DDJHMu0z.js} +1 -1
- package/dist/rcs-web/assets/ShareLanding-DG5JbaWg.js +1 -0
- package/dist/rcs-web/assets/{TeamCreate-CaoinTSG.js → TeamCreate-D_AnatYF.js} +1 -1
- package/dist/rcs-web/assets/{TeamDetail-D5ahen24.js → TeamDetail-C1FFiAj2.js} +2 -2
- package/dist/rcs-web/assets/{TeamList-qCuKKSH3.js → TeamList-tfsnwvZG.js} +1 -1
- package/dist/rcs-web/assets/{TeamSettings-BaIwImrp.js → TeamSettings-FeTuY9_I.js} +1 -1
- package/dist/rcs-web/assets/{UserSearchInput-BxcYR_HU.js → UserSearchInput-Bu3RXDYh.js} +1 -1
- package/dist/rcs-web/assets/{UserSettings-zfGfcuWs.js → UserSettings-BrjmELAZ.js} +1 -1
- package/dist/rcs-web/assets/{arc-DwAbF6eM.js → arc-Di9w8tGK.js} +1 -1
- package/dist/rcs-web/assets/{architectureDiagram-3BPJPVTR-uMOwOwiN.js → architectureDiagram-3BPJPVTR-FT-IsfVA.js} +1 -1
- package/{packages/remote-control-server/web/dist/assets/blockDiagram-GPEHLZMM-B5BqFTkP.js → dist/rcs-web/assets/blockDiagram-GPEHLZMM-DryBvbP3.js} +1 -1
- package/dist/rcs-web/assets/{c4Diagram-AAUBKEIU-D6eienz2.js → c4Diagram-AAUBKEIU-HWAmxH56.js} +1 -1
- package/dist/rcs-web/assets/channel-N4W03sy5.js +1 -0
- package/dist/rcs-web/assets/{chunk-2J33WTMH-DqVxv8yW.js → chunk-2J33WTMH-AdjHpC7B.js} +1 -1
- package/dist/rcs-web/assets/{chunk-4BX2VUAB-X5o4x8om.js → chunk-4BX2VUAB-CpZ-59LR.js} +1 -1
- package/dist/rcs-web/assets/{chunk-55IACEB6-D7G25_Y5.js → chunk-55IACEB6-BBSmURaz.js} +1 -1
- package/{packages/remote-control-server/web/dist/assets/chunk-727SXJPM-CoXI1FIy.js → dist/rcs-web/assets/chunk-727SXJPM-1k6tgn8s.js} +1 -1
- package/dist/rcs-web/assets/{chunk-AQP2D5EJ-C73Crhqe.js → chunk-AQP2D5EJ-im0ij4Kj.js} +1 -1
- package/dist/rcs-web/assets/{chunk-FMBD7UC4-DVzxIsSE.js → chunk-FMBD7UC4-Cs3z8_hw.js} +1 -1
- package/dist/rcs-web/assets/{chunk-ND2GUHAM-C6_oEhLf.js → chunk-ND2GUHAM-BA9iE2wc.js} +1 -1
- package/dist/rcs-web/assets/{chunk-QZHKN3VN-COvH7k5r.js → chunk-QZHKN3VN-DbvzoKsw.js} +1 -1
- package/dist/rcs-web/assets/classDiagram-4FO5ZUOK-CcBgewcu.js +1 -0
- package/dist/rcs-web/assets/classDiagram-v2-Q7XG4LA2-CcBgewcu.js +1 -0
- package/dist/rcs-web/assets/{code-block-IT6T5CEO-CE-2f_-K.js → code-block-IT6T5CEO-wgmiR0vF.js} +1 -1
- package/dist/rcs-web/assets/{copy-9pzb1Po6.js → copy-BD6qrRfd.js} +1 -1
- package/dist/rcs-web/assets/{cose-bilkent-S5V4N54A-B9sMDFRe.js → cose-bilkent-S5V4N54A-DT4C5Yz2.js} +1 -1
- package/dist/rcs-web/assets/{dagre-BM42HDAG-DB1jXylM.js → dagre-BM42HDAG-CRf1H6Hv.js} +1 -1
- package/dist/rcs-web/assets/{diagram-2AECGRRQ-MNuqSRmg.js → diagram-2AECGRRQ-BChRpS-u.js} +1 -1
- package/dist/rcs-web/assets/{diagram-5GNKFQAL-BZwhvaEY.js → diagram-5GNKFQAL-BicbIYus.js} +1 -1
- package/dist/rcs-web/assets/{diagram-KO2AKTUF-3Wp2PnI2.js → diagram-KO2AKTUF-DCfQNjGq.js} +1 -1
- package/dist/rcs-web/assets/{diagram-LMA3HP47-CTcV1SBj.js → diagram-LMA3HP47-mMyd4aUd.js} +1 -1
- package/dist/rcs-web/assets/{diagram-OG6HWLK6-DzXhSQDC.js → diagram-OG6HWLK6-DUWhyWTm.js} +1 -1
- package/dist/rcs-web/assets/dialog-DympH6_o.js +1 -0
- package/dist/rcs-web/assets/{erDiagram-TEJ5UH35-CwSihkB8.js → erDiagram-TEJ5UH35-DnBH3GMK.js} +1 -1
- package/dist/rcs-web/assets/external-link-J-x6ty1h.js +6 -0
- package/dist/rcs-web/assets/{flowDiagram-I6XJVG4X-BSuXctT4.js → flowDiagram-I6XJVG4X-Ba7lo6ds.js} +1 -1
- package/{packages/remote-control-server/web/dist/assets/ganttDiagram-6RSMTGT7-B87oxjmY.js → dist/rcs-web/assets/ganttDiagram-6RSMTGT7-CKkj67eu.js} +1 -1
- package/dist/rcs-web/assets/{gitGraphDiagram-PVQCEYII-BRrwOi3C.js → gitGraphDiagram-PVQCEYII-205YdSRe.js} +1 -1
- package/dist/rcs-web/assets/{infoDiagram-5YYISTIA-B-8QXS0n.js → infoDiagram-5YYISTIA-CpPvGigJ.js} +1 -1
- package/dist/rcs-web/assets/{ishikawaDiagram-YF4QCWOH-Bau9MU6C.js → ishikawaDiagram-YF4QCWOH-D0ZEWQy7.js} +1 -1
- package/dist/rcs-web/assets/{journeyDiagram-JHISSGLW-D_tAp--R.js → journeyDiagram-JHISSGLW-DVl0M9a7.js} +1 -1
- package/dist/rcs-web/assets/{kanban-definition-UN3LZRKU---UIvjMZ.js → kanban-definition-UN3LZRKU-Dkr8uJC-.js} +1 -1
- package/dist/rcs-web/assets/{linear-CIDLjd5h.js → linear-CIdvseqY.js} +1 -1
- package/dist/rcs-web/assets/main-B8hkVvfg.js +265 -0
- package/dist/rcs-web/assets/main-C2O-g177.css +1 -0
- package/dist/rcs-web/assets/{mermaid-VLURNSYL-Cu5A5sMk.js → mermaid-VLURNSYL-DdTSeoZS.js} +4 -4
- package/dist/rcs-web/assets/{mermaid.core-CEJOtCGw.js → mermaid.core-CtvzCSq2.js} +5 -5
- package/{packages/remote-control-server/web/dist/assets/mindmap-definition-RKZ34NQL-ldyccyCP.js → dist/rcs-web/assets/mindmap-definition-RKZ34NQL-CMlDCaV_.js} +1 -1
- package/dist/rcs-web/assets/{pieDiagram-4H26LBE5-CmghofeF.js → pieDiagram-4H26LBE5-C6xMizTL.js} +1 -1
- package/{packages/remote-control-server/web/dist/assets/quadrantDiagram-W4KKPZXB-B-2N2UHr.js → dist/rcs-web/assets/quadrantDiagram-W4KKPZXB-D6epraE1.js} +1 -1
- package/dist/rcs-web/assets/{requirementDiagram-4Y6WPE33-39jlO9Y8.js → requirementDiagram-4Y6WPE33-BHmML6bk.js} +1 -1
- package/{packages/remote-control-server/web/dist/assets/sankeyDiagram-5OEKKPKP-DdY7KNFB.js → dist/rcs-web/assets/sankeyDiagram-5OEKKPKP-CIKij54Y.js} +1 -1
- package/dist/rcs-web/assets/{sequenceDiagram-3UESZ5HK-D2k5rX6x.js → sequenceDiagram-3UESZ5HK-CY0y5zdR.js} +1 -1
- package/dist/rcs-web/assets/{stateDiagram-AJRCARHV-CP9N457o.js → stateDiagram-AJRCARHV-FBhNz1Lc.js} +1 -1
- package/dist/rcs-web/assets/{stateDiagram-v2-BHNVJYJU-CPhZYlL0.js → stateDiagram-v2-BHNVJYJU-m7ruBTu5.js} +1 -1
- package/{packages/remote-control-server/web/dist/assets/timeline-definition-PNZ67QCA-DSEPBO8O.js → dist/rcs-web/assets/timeline-definition-PNZ67QCA-CJopHs1x.js} +1 -1
- package/dist/rcs-web/assets/{vennDiagram-CIIHVFJN-CkNMwCJ3.js → vennDiagram-CIIHVFJN-DF_uHOP7.js} +1 -1
- package/dist/rcs-web/assets/{wardleyDiagram-YWT4CUSO-Cxd-F60s.js → wardleyDiagram-YWT4CUSO-DQmjIZJA.js} +1 -1
- package/{packages/remote-control-server/web/dist/assets/xychartDiagram-2RQKCTM6-BLL105NN.js → dist/rcs-web/assets/xychartDiagram-2RQKCTM6-v8zL-j4G.js} +1 -1
- package/dist/rcs-web/index.html +2 -2
- package/package.json +1 -1
- package/packages/remote-control-server/src/__tests__/artifacts.test.ts +370 -0
- package/packages/remote-control-server/src/__tests__/attach-wait.test.ts +54 -0
- package/packages/remote-control-server/src/__tests__/attach.test.ts +37 -0
- package/packages/remote-control-server/src/__tests__/helpers/mock-config.ts +1 -0
- package/packages/remote-control-server/src/__tests__/low-priority-fixes.test.ts +95 -0
- package/packages/remote-control-server/src/__tests__/routes.test.ts +69 -0
- package/packages/remote-control-server/src/config.ts +6 -0
- package/packages/remote-control-server/src/db/rcs-schema.sql +23 -0
- package/packages/remote-control-server/src/index.ts +9 -0
- package/packages/remote-control-server/src/registerRoutes.ts +8 -0
- package/packages/remote-control-server/src/routes/v1/artifacts.ts +179 -0
- package/packages/remote-control-server/src/routes/v1/environments.ts +17 -9
- package/packages/remote-control-server/src/routes/v1/environments.work.ts +2 -2
- package/packages/remote-control-server/src/routes/v1/sessions.ts +39 -9
- package/packages/remote-control-server/src/routes/web/artifacts.ts +249 -0
- package/packages/remote-control-server/src/routes/web/sessions.ts +25 -22
- package/packages/remote-control-server/src/services/artifacts.ts +378 -0
- package/packages/remote-control-server/src/services/environment.ts +25 -0
- package/packages/remote-control-server/web/dist/assets/{AdminPanel-CqP_94xa.js → AdminPanel-94uchXH7.js} +1 -1
- package/packages/remote-control-server/web/dist/assets/ArtifactView-CT0Fu4U5.js +6 -0
- package/packages/remote-control-server/web/dist/assets/ArtifactsGallery-DgK1CSno.js +339 -0
- package/{dist/rcs-web/assets/Claim-BvfARQ6Q.js → packages/remote-control-server/web/dist/assets/Claim-C7V1Q01Y.js} +1 -1
- package/packages/remote-control-server/web/dist/assets/{Dashboard-BDGi4XpN.js → Dashboard-NLM7Kgm8.js} +2 -2
- package/{dist/rcs-web/assets/Join-PPDYBhsJ.js → packages/remote-control-server/web/dist/assets/Join-BhjsvbAP.js} +1 -1
- package/packages/remote-control-server/web/dist/assets/{Login-JprQIEpr.js → Login-DRFE4F-F.js} +1 -1
- package/packages/remote-control-server/web/dist/assets/{Register-cuGuAE83.js → Register-FgLOFB4h.js} +1 -1
- package/packages/remote-control-server/web/dist/assets/SessionDetail-3P77L-sJ.js +60 -0
- package/packages/remote-control-server/web/dist/assets/SessionVisibilityBadge-raEV1sW8.js +11 -0
- package/packages/remote-control-server/web/dist/assets/{Setup-Buwa9Y3M.js → Setup-DDJHMu0z.js} +1 -1
- package/packages/remote-control-server/web/dist/assets/ShareLanding-DG5JbaWg.js +1 -0
- package/packages/remote-control-server/web/dist/assets/{TeamCreate-CaoinTSG.js → TeamCreate-D_AnatYF.js} +1 -1
- package/packages/remote-control-server/web/dist/assets/{TeamDetail-D5ahen24.js → TeamDetail-C1FFiAj2.js} +2 -2
- package/packages/remote-control-server/web/dist/assets/{TeamList-qCuKKSH3.js → TeamList-tfsnwvZG.js} +1 -1
- package/packages/remote-control-server/web/dist/assets/{TeamSettings-BaIwImrp.js → TeamSettings-FeTuY9_I.js} +1 -1
- package/packages/remote-control-server/web/dist/assets/{UserSearchInput-BxcYR_HU.js → UserSearchInput-Bu3RXDYh.js} +1 -1
- package/packages/remote-control-server/web/dist/assets/{UserSettings-zfGfcuWs.js → UserSettings-BrjmELAZ.js} +1 -1
- package/packages/remote-control-server/web/dist/assets/{arc-DwAbF6eM.js → arc-Di9w8tGK.js} +1 -1
- package/packages/remote-control-server/web/dist/assets/{architectureDiagram-3BPJPVTR-uMOwOwiN.js → architectureDiagram-3BPJPVTR-FT-IsfVA.js} +1 -1
- package/{dist/rcs-web/assets/blockDiagram-GPEHLZMM-B5BqFTkP.js → packages/remote-control-server/web/dist/assets/blockDiagram-GPEHLZMM-DryBvbP3.js} +1 -1
- package/packages/remote-control-server/web/dist/assets/{c4Diagram-AAUBKEIU-D6eienz2.js → c4Diagram-AAUBKEIU-HWAmxH56.js} +1 -1
- package/packages/remote-control-server/web/dist/assets/channel-N4W03sy5.js +1 -0
- package/packages/remote-control-server/web/dist/assets/{chunk-2J33WTMH-DqVxv8yW.js → chunk-2J33WTMH-AdjHpC7B.js} +1 -1
- package/packages/remote-control-server/web/dist/assets/{chunk-4BX2VUAB-X5o4x8om.js → chunk-4BX2VUAB-CpZ-59LR.js} +1 -1
- package/packages/remote-control-server/web/dist/assets/{chunk-55IACEB6-D7G25_Y5.js → chunk-55IACEB6-BBSmURaz.js} +1 -1
- package/{dist/rcs-web/assets/chunk-727SXJPM-CoXI1FIy.js → packages/remote-control-server/web/dist/assets/chunk-727SXJPM-1k6tgn8s.js} +1 -1
- package/packages/remote-control-server/web/dist/assets/{chunk-AQP2D5EJ-C73Crhqe.js → chunk-AQP2D5EJ-im0ij4Kj.js} +1 -1
- package/packages/remote-control-server/web/dist/assets/{chunk-FMBD7UC4-DVzxIsSE.js → chunk-FMBD7UC4-Cs3z8_hw.js} +1 -1
- package/packages/remote-control-server/web/dist/assets/{chunk-ND2GUHAM-C6_oEhLf.js → chunk-ND2GUHAM-BA9iE2wc.js} +1 -1
- package/packages/remote-control-server/web/dist/assets/{chunk-QZHKN3VN-COvH7k5r.js → chunk-QZHKN3VN-DbvzoKsw.js} +1 -1
- package/packages/remote-control-server/web/dist/assets/classDiagram-4FO5ZUOK-CcBgewcu.js +1 -0
- package/packages/remote-control-server/web/dist/assets/classDiagram-v2-Q7XG4LA2-CcBgewcu.js +1 -0
- package/packages/remote-control-server/web/dist/assets/{code-block-IT6T5CEO-CE-2f_-K.js → code-block-IT6T5CEO-wgmiR0vF.js} +1 -1
- package/packages/remote-control-server/web/dist/assets/{copy-9pzb1Po6.js → copy-BD6qrRfd.js} +1 -1
- package/packages/remote-control-server/web/dist/assets/{cose-bilkent-S5V4N54A-B9sMDFRe.js → cose-bilkent-S5V4N54A-DT4C5Yz2.js} +1 -1
- package/packages/remote-control-server/web/dist/assets/{dagre-BM42HDAG-DB1jXylM.js → dagre-BM42HDAG-CRf1H6Hv.js} +1 -1
- package/packages/remote-control-server/web/dist/assets/{diagram-2AECGRRQ-MNuqSRmg.js → diagram-2AECGRRQ-BChRpS-u.js} +1 -1
- package/packages/remote-control-server/web/dist/assets/{diagram-5GNKFQAL-BZwhvaEY.js → diagram-5GNKFQAL-BicbIYus.js} +1 -1
- package/packages/remote-control-server/web/dist/assets/{diagram-KO2AKTUF-3Wp2PnI2.js → diagram-KO2AKTUF-DCfQNjGq.js} +1 -1
- package/packages/remote-control-server/web/dist/assets/{diagram-LMA3HP47-CTcV1SBj.js → diagram-LMA3HP47-mMyd4aUd.js} +1 -1
- package/packages/remote-control-server/web/dist/assets/{diagram-OG6HWLK6-DzXhSQDC.js → diagram-OG6HWLK6-DUWhyWTm.js} +1 -1
- package/packages/remote-control-server/web/dist/assets/dialog-DympH6_o.js +1 -0
- package/packages/remote-control-server/web/dist/assets/{erDiagram-TEJ5UH35-CwSihkB8.js → erDiagram-TEJ5UH35-DnBH3GMK.js} +1 -1
- package/packages/remote-control-server/web/dist/assets/external-link-J-x6ty1h.js +6 -0
- package/packages/remote-control-server/web/dist/assets/{flowDiagram-I6XJVG4X-BSuXctT4.js → flowDiagram-I6XJVG4X-Ba7lo6ds.js} +1 -1
- package/{dist/rcs-web/assets/ganttDiagram-6RSMTGT7-B87oxjmY.js → packages/remote-control-server/web/dist/assets/ganttDiagram-6RSMTGT7-CKkj67eu.js} +1 -1
- package/packages/remote-control-server/web/dist/assets/{gitGraphDiagram-PVQCEYII-BRrwOi3C.js → gitGraphDiagram-PVQCEYII-205YdSRe.js} +1 -1
- package/packages/remote-control-server/web/dist/assets/{infoDiagram-5YYISTIA-B-8QXS0n.js → infoDiagram-5YYISTIA-CpPvGigJ.js} +1 -1
- package/packages/remote-control-server/web/dist/assets/{ishikawaDiagram-YF4QCWOH-Bau9MU6C.js → ishikawaDiagram-YF4QCWOH-D0ZEWQy7.js} +1 -1
- package/packages/remote-control-server/web/dist/assets/{journeyDiagram-JHISSGLW-D_tAp--R.js → journeyDiagram-JHISSGLW-DVl0M9a7.js} +1 -1
- package/packages/remote-control-server/web/dist/assets/{kanban-definition-UN3LZRKU---UIvjMZ.js → kanban-definition-UN3LZRKU-Dkr8uJC-.js} +1 -1
- package/packages/remote-control-server/web/dist/assets/{linear-CIDLjd5h.js → linear-CIdvseqY.js} +1 -1
- package/packages/remote-control-server/web/dist/assets/main-B8hkVvfg.js +265 -0
- package/packages/remote-control-server/web/dist/assets/main-C2O-g177.css +1 -0
- package/packages/remote-control-server/web/dist/assets/{mermaid-VLURNSYL-Cu5A5sMk.js → mermaid-VLURNSYL-DdTSeoZS.js} +4 -4
- package/packages/remote-control-server/web/dist/assets/{mermaid.core-CEJOtCGw.js → mermaid.core-CtvzCSq2.js} +5 -5
- package/{dist/rcs-web/assets/mindmap-definition-RKZ34NQL-ldyccyCP.js → packages/remote-control-server/web/dist/assets/mindmap-definition-RKZ34NQL-CMlDCaV_.js} +1 -1
- package/packages/remote-control-server/web/dist/assets/{pieDiagram-4H26LBE5-CmghofeF.js → pieDiagram-4H26LBE5-C6xMizTL.js} +1 -1
- package/{dist/rcs-web/assets/quadrantDiagram-W4KKPZXB-B-2N2UHr.js → packages/remote-control-server/web/dist/assets/quadrantDiagram-W4KKPZXB-D6epraE1.js} +1 -1
- package/packages/remote-control-server/web/dist/assets/{requirementDiagram-4Y6WPE33-39jlO9Y8.js → requirementDiagram-4Y6WPE33-BHmML6bk.js} +1 -1
- package/{dist/rcs-web/assets/sankeyDiagram-5OEKKPKP-DdY7KNFB.js → packages/remote-control-server/web/dist/assets/sankeyDiagram-5OEKKPKP-CIKij54Y.js} +1 -1
- package/packages/remote-control-server/web/dist/assets/{sequenceDiagram-3UESZ5HK-D2k5rX6x.js → sequenceDiagram-3UESZ5HK-CY0y5zdR.js} +1 -1
- package/packages/remote-control-server/web/dist/assets/{stateDiagram-AJRCARHV-CP9N457o.js → stateDiagram-AJRCARHV-FBhNz1Lc.js} +1 -1
- package/packages/remote-control-server/web/dist/assets/{stateDiagram-v2-BHNVJYJU-CPhZYlL0.js → stateDiagram-v2-BHNVJYJU-m7ruBTu5.js} +1 -1
- package/{dist/rcs-web/assets/timeline-definition-PNZ67QCA-DSEPBO8O.js → packages/remote-control-server/web/dist/assets/timeline-definition-PNZ67QCA-CJopHs1x.js} +1 -1
- package/packages/remote-control-server/web/dist/assets/{vennDiagram-CIIHVFJN-CkNMwCJ3.js → vennDiagram-CIIHVFJN-DF_uHOP7.js} +1 -1
- package/packages/remote-control-server/web/dist/assets/{wardleyDiagram-YWT4CUSO-Cxd-F60s.js → wardleyDiagram-YWT4CUSO-DQmjIZJA.js} +1 -1
- package/{dist/rcs-web/assets/xychartDiagram-2RQKCTM6-BLL105NN.js → packages/remote-control-server/web/dist/assets/xychartDiagram-2RQKCTM6-v8zL-j4G.js} +1 -1
- package/packages/remote-control-server/web/dist/index.html +2 -2
- package/dist/rcs-web/assets/SessionDetail-D-xhkyLo.js +0 -65
- package/dist/rcs-web/assets/SessionVisibilityBadge-91WyR9K6.js +0 -11
- package/dist/rcs-web/assets/ShareLanding-DhwgJb6V.js +0 -1
- package/dist/rcs-web/assets/channel-CCfqpGSl.js +0 -1
- package/dist/rcs-web/assets/classDiagram-4FO5ZUOK-DzNdVs3v.js +0 -1
- package/dist/rcs-web/assets/classDiagram-v2-Q7XG4LA2-DzNdVs3v.js +0 -1
- package/dist/rcs-web/assets/main-DhbquBXW.css +0 -1
- package/dist/rcs-web/assets/main-N3GYCdLF.js +0 -260
- package/packages/remote-control-server/web/dist/assets/SessionDetail-D-xhkyLo.js +0 -65
- package/packages/remote-control-server/web/dist/assets/SessionVisibilityBadge-91WyR9K6.js +0 -11
- package/packages/remote-control-server/web/dist/assets/ShareLanding-DhwgJb6V.js +0 -1
- package/packages/remote-control-server/web/dist/assets/channel-CCfqpGSl.js +0 -1
- package/packages/remote-control-server/web/dist/assets/classDiagram-4FO5ZUOK-DzNdVs3v.js +0 -1
- package/packages/remote-control-server/web/dist/assets/classDiagram-v2-Q7XG4LA2-DzNdVs3v.js +0 -1
- package/packages/remote-control-server/web/dist/assets/main-DhbquBXW.css +0 -1
- package/packages/remote-control-server/web/dist/assets/main-N3GYCdLF.js +0 -260
|
@@ -0,0 +1,378 @@
|
|
|
1
|
+
import { nanoid } from 'nanoid'
|
|
2
|
+
import type { Database } from 'bun:sqlite'
|
|
3
|
+
import { error as logError, log } from '../logger'
|
|
4
|
+
import { getDb } from '../db/sqlite'
|
|
5
|
+
import { isSessionVisibleToUser } from './session'
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* Artifacts — self-hosted HTML pages uploaded by the CLI `artifact` tool or
|
|
9
|
+
* created from the web UI gallery.
|
|
10
|
+
*
|
|
11
|
+
* Mirrors the upstream cloud-artifacts semantics: the `id` is an unguessable
|
|
12
|
+
* nanoid that doubles as the share slug (URL-is-the-secret), passing `hash`
|
|
13
|
+
* on upload overwrites in place (URL stays stable, version bumps), and TTL
|
|
14
|
+
* bounds retention (7 or 30 days).
|
|
15
|
+
*/
|
|
16
|
+
|
|
17
|
+
export const ARTIFACT_ALLOWED_TTLS = [7, 30] as const
|
|
18
|
+
export type ArtifactTtl = (typeof ARTIFACT_ALLOWED_TTLS)[number]
|
|
19
|
+
|
|
20
|
+
export const ARTIFACT_MAX_BYTES = 10 * 1024 * 1024
|
|
21
|
+
|
|
22
|
+
/** Same charset contract as the upstream service. */
|
|
23
|
+
const HASH_PATTERN = /^[A-Za-z0-9_-]{1,128}$/
|
|
24
|
+
|
|
25
|
+
export interface ArtifactRow {
|
|
26
|
+
id: string
|
|
27
|
+
session_id: string | null
|
|
28
|
+
team_id: string | null
|
|
29
|
+
title: string | null
|
|
30
|
+
content_type: string
|
|
31
|
+
content: string
|
|
32
|
+
size: number
|
|
33
|
+
version: number
|
|
34
|
+
created_by: string | null
|
|
35
|
+
created_at: string
|
|
36
|
+
updated_at: string
|
|
37
|
+
expires_at: string | null
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
export type ArtifactMeta = Omit<ArtifactRow, 'content'>
|
|
41
|
+
|
|
42
|
+
export interface CreateArtifactParams {
|
|
43
|
+
html: string
|
|
44
|
+
/** Overwrite the artifact with this id (URL stays stable). */
|
|
45
|
+
hash?: string
|
|
46
|
+
ttl?: ArtifactTtl
|
|
47
|
+
sessionId?: string
|
|
48
|
+
title?: string
|
|
49
|
+
createdBy?: string
|
|
50
|
+
contentType?: string
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
export interface CreateArtifactResult {
|
|
54
|
+
id: string
|
|
55
|
+
expiresAt: string
|
|
56
|
+
created: boolean
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
function toMeta(row: ArtifactRow): ArtifactMeta {
|
|
60
|
+
const { content: _content, ...meta } = row
|
|
61
|
+
return meta
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
function nowIso(): string {
|
|
65
|
+
return new Date().toISOString()
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
function isExpired(row: ArtifactRow): boolean {
|
|
69
|
+
if (!row.expires_at) return false
|
|
70
|
+
return new Date(row.expires_at).getTime() < Date.now()
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
/** Derive the owning team (if any) for a session — denormalized onto the
|
|
74
|
+
* artifact so the team gallery query is a single index scan. */
|
|
75
|
+
function deriveTeamId(
|
|
76
|
+
db: Database,
|
|
77
|
+
sessionId: string | undefined,
|
|
78
|
+
): string | null {
|
|
79
|
+
if (!sessionId) return null
|
|
80
|
+
try {
|
|
81
|
+
const row = db
|
|
82
|
+
.query(
|
|
83
|
+
`SELECT owner_id FROM session_owners
|
|
84
|
+
WHERE session_id = $sid AND owner_type = 'team'
|
|
85
|
+
LIMIT 1`,
|
|
86
|
+
)
|
|
87
|
+
.get({ $sid: sessionId }) as { owner_id: string } | undefined
|
|
88
|
+
return row?.owner_id ?? null
|
|
89
|
+
} catch (err) {
|
|
90
|
+
logError(`[artifacts] deriveTeamId failed session=${sessionId}:`, err)
|
|
91
|
+
return null
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
export function getArtifactRow(id: string): ArtifactRow | null {
|
|
96
|
+
try {
|
|
97
|
+
const row = getDb()
|
|
98
|
+
.query('SELECT * FROM artifacts WHERE id = $id')
|
|
99
|
+
.get({ $id: id }) as ArtifactRow | null
|
|
100
|
+
if (!row) return null
|
|
101
|
+
// Expired artifacts behave as deleted for every reader.
|
|
102
|
+
return isExpired(row) ? null : row
|
|
103
|
+
} catch (err) {
|
|
104
|
+
logError(`[artifacts] getArtifactRow failed id=${id}:`, err)
|
|
105
|
+
return null
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
export function getArtifactContent(id: string): {
|
|
110
|
+
content: string
|
|
111
|
+
contentType: string
|
|
112
|
+
} | null {
|
|
113
|
+
const row = getArtifactRow(id)
|
|
114
|
+
if (!row) return null
|
|
115
|
+
return { content: row.content, contentType: row.content_type }
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
export function createArtifact(
|
|
119
|
+
params: CreateArtifactParams,
|
|
120
|
+
): CreateArtifactResult {
|
|
121
|
+
const db = getDb()
|
|
122
|
+
const html = params.html
|
|
123
|
+
const size = Buffer.byteLength(html, 'utf8')
|
|
124
|
+
if (size > ARTIFACT_MAX_BYTES) {
|
|
125
|
+
throw new ArtifactError(
|
|
126
|
+
`payload_too_large`,
|
|
127
|
+
`Artifact is ${size} bytes; limit is ${ARTIFACT_MAX_BYTES}.`,
|
|
128
|
+
)
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
const ttl = params.ttl ?? 7
|
|
132
|
+
if (!ARTIFACT_ALLOWED_TTLS.includes(ttl)) {
|
|
133
|
+
throw new ArtifactError('invalid_ttl', `ttl must be 7 or 30 (got ${ttl}).`)
|
|
134
|
+
}
|
|
135
|
+
if (params.hash !== undefined && !HASH_PATTERN.test(params.hash)) {
|
|
136
|
+
throw new ArtifactError(
|
|
137
|
+
'invalid_hash',
|
|
138
|
+
'hash must match ^[A-Za-z0-9_-]{1,128}$',
|
|
139
|
+
)
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
const expiresAt = new Date(
|
|
143
|
+
Date.now() + ttl * 24 * 60 * 60 * 1000,
|
|
144
|
+
).toISOString()
|
|
145
|
+
const now = nowIso()
|
|
146
|
+
const sessionId = params.sessionId ?? null
|
|
147
|
+
const teamId = deriveTeamId(db, sessionId ?? undefined)
|
|
148
|
+
|
|
149
|
+
// Overwrite path — keep the URL stable, bump version, refresh TTL.
|
|
150
|
+
if (params.hash) {
|
|
151
|
+
const existing = db
|
|
152
|
+
.query('SELECT id FROM artifacts WHERE id = $id')
|
|
153
|
+
.get({ $id: params.hash }) as { id: string } | null
|
|
154
|
+
if (existing) {
|
|
155
|
+
db.query(
|
|
156
|
+
`UPDATE artifacts
|
|
157
|
+
SET content = $content, size = $size, title = COALESCE($title, title),
|
|
158
|
+
version = version + 1, updated_at = $now, expires_at = $expires,
|
|
159
|
+
session_id = COALESCE($session_id, session_id),
|
|
160
|
+
team_id = COALESCE($team_id, team_id)
|
|
161
|
+
WHERE id = $id`,
|
|
162
|
+
).run({
|
|
163
|
+
$id: params.hash,
|
|
164
|
+
$content: html,
|
|
165
|
+
$size: size,
|
|
166
|
+
$title: params.title ?? null,
|
|
167
|
+
$now: now,
|
|
168
|
+
$expires: expiresAt,
|
|
169
|
+
$session_id: sessionId,
|
|
170
|
+
$team_id: teamId,
|
|
171
|
+
})
|
|
172
|
+
return { id: params.hash, expiresAt, created: false }
|
|
173
|
+
}
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
const id = params.hash ?? nanoid(21)
|
|
177
|
+
const title = params.title ?? null
|
|
178
|
+
const createdBy = params.createdBy ?? null
|
|
179
|
+
db.query(
|
|
180
|
+
`INSERT INTO artifacts
|
|
181
|
+
(id, session_id, team_id, title, content_type, content, size, version,
|
|
182
|
+
created_by, created_at, updated_at, expires_at)
|
|
183
|
+
VALUES ($id, $session_id, $team_id, $title, $content_type, $content,
|
|
184
|
+
$size, 1, $created_by, $now, $now, $expires)`,
|
|
185
|
+
).run({
|
|
186
|
+
$id: id,
|
|
187
|
+
$session_id: sessionId,
|
|
188
|
+
$team_id: teamId,
|
|
189
|
+
$title: title,
|
|
190
|
+
$content_type: params.contentType ?? 'text/html; charset=utf-8',
|
|
191
|
+
$content: html,
|
|
192
|
+
$size: size,
|
|
193
|
+
$created_by: createdBy,
|
|
194
|
+
$now: now,
|
|
195
|
+
$expires: expiresAt,
|
|
196
|
+
})
|
|
197
|
+
|
|
198
|
+
return { id, expiresAt, created: true }
|
|
199
|
+
}
|
|
200
|
+
|
|
201
|
+
export function deleteArtifact(id: string): boolean {
|
|
202
|
+
try {
|
|
203
|
+
const result = getDb()
|
|
204
|
+
.query('DELETE FROM artifacts WHERE id = $id')
|
|
205
|
+
.run({ $id: id })
|
|
206
|
+
return (result as unknown as { changes?: number }).changes === 1
|
|
207
|
+
} catch (err) {
|
|
208
|
+
logError(`[artifacts] deleteArtifact failed id=${id}:`, err)
|
|
209
|
+
return false
|
|
210
|
+
}
|
|
211
|
+
}
|
|
212
|
+
|
|
213
|
+
/**
|
|
214
|
+
* Whether a user can see an artifact's metadata. Follows session visibility
|
|
215
|
+
* (owner / team member / share grantee); session-less artifacts (web gallery
|
|
216
|
+
* creations) are visible to their creator and to members of the owning team.
|
|
217
|
+
*/
|
|
218
|
+
export function isArtifactVisibleToUser(
|
|
219
|
+
id: string,
|
|
220
|
+
userId: string,
|
|
221
|
+
isAdmin = false,
|
|
222
|
+
): boolean {
|
|
223
|
+
const db = getDb()
|
|
224
|
+
const row = getArtifactRow(id)
|
|
225
|
+
if (!row) return false
|
|
226
|
+
if (isAdmin) return true
|
|
227
|
+
|
|
228
|
+
if (row.created_by === userId) return true
|
|
229
|
+
|
|
230
|
+
if (row.session_id) {
|
|
231
|
+
if (isSessionVisibleToUser(row.session_id, userId, db)) return true
|
|
232
|
+
}
|
|
233
|
+
|
|
234
|
+
if (row.team_id) {
|
|
235
|
+
const member = db
|
|
236
|
+
.query(
|
|
237
|
+
'SELECT 1 FROM team_members WHERE team_id = $teamId AND user_id = $userId LIMIT 1',
|
|
238
|
+
)
|
|
239
|
+
.get({ $teamId: row.team_id, $userId: userId })
|
|
240
|
+
if (member) return true
|
|
241
|
+
}
|
|
242
|
+
|
|
243
|
+
return false
|
|
244
|
+
}
|
|
245
|
+
|
|
246
|
+
/**
|
|
247
|
+
* Whether a user can delete/update an artifact: system admin, the artifact
|
|
248
|
+
* creator, or a manager of the owning session/team.
|
|
249
|
+
*/
|
|
250
|
+
export function canManageArtifact(
|
|
251
|
+
id: string,
|
|
252
|
+
userId: string,
|
|
253
|
+
isAdmin = false,
|
|
254
|
+
): boolean {
|
|
255
|
+
const db = getDb()
|
|
256
|
+
const row = getArtifactRow(id)
|
|
257
|
+
if (!row) return false
|
|
258
|
+
if (isAdmin) return true
|
|
259
|
+
if (row.created_by === userId) return true
|
|
260
|
+
|
|
261
|
+
if (row.session_id) {
|
|
262
|
+
// Reuse session management rules (direct owner / team owner+admin / admin).
|
|
263
|
+
const userRole = db
|
|
264
|
+
.query('SELECT role FROM users WHERE id = $userId')
|
|
265
|
+
.get({ $userId: userId }) as { role: string } | null
|
|
266
|
+
if (userRole?.role === 'admin') return true
|
|
267
|
+
|
|
268
|
+
const directOwner = db
|
|
269
|
+
.query(
|
|
270
|
+
`SELECT 1 FROM session_owners
|
|
271
|
+
WHERE session_id = $sid AND owner_type = 'user' AND owner_id = $uid
|
|
272
|
+
LIMIT 1`,
|
|
273
|
+
)
|
|
274
|
+
.get({ $sid: row.session_id, $uid: userId })
|
|
275
|
+
if (directOwner) return true
|
|
276
|
+
|
|
277
|
+
const teamManager = db
|
|
278
|
+
.query(
|
|
279
|
+
`SELECT 1 FROM session_owners so
|
|
280
|
+
JOIN team_members tm ON tm.team_id = so.owner_id
|
|
281
|
+
WHERE so.session_id = $sid
|
|
282
|
+
AND so.owner_type = 'team'
|
|
283
|
+
AND tm.user_id = $uid
|
|
284
|
+
AND tm.role IN ('owner', 'admin')
|
|
285
|
+
LIMIT 1`,
|
|
286
|
+
)
|
|
287
|
+
.get({ $sid: row.session_id, $uid: userId })
|
|
288
|
+
if (teamManager) return true
|
|
289
|
+
}
|
|
290
|
+
|
|
291
|
+
if (row.team_id) {
|
|
292
|
+
const teamManager = db
|
|
293
|
+
.query(
|
|
294
|
+
`SELECT 1 FROM team_members
|
|
295
|
+
WHERE team_id = $teamId AND user_id = $userId
|
|
296
|
+
AND role IN ('owner', 'admin')
|
|
297
|
+
LIMIT 1`,
|
|
298
|
+
)
|
|
299
|
+
.get({ $teamId: row.team_id, $userId: userId })
|
|
300
|
+
if (teamManager) return true
|
|
301
|
+
}
|
|
302
|
+
|
|
303
|
+
return false
|
|
304
|
+
}
|
|
305
|
+
|
|
306
|
+
export interface ListArtifactsFilter {
|
|
307
|
+
sessionId?: string
|
|
308
|
+
teamId?: string
|
|
309
|
+
}
|
|
310
|
+
|
|
311
|
+
/**
|
|
312
|
+
* List artifact metadata visible to a user. When `sessionId` is given the
|
|
313
|
+
* caller must already have passed the session-visibility check (route-level);
|
|
314
|
+
* otherwise rows are filtered per-row via isArtifactVisibleToUser.
|
|
315
|
+
*/
|
|
316
|
+
export function listArtifactsForUser(
|
|
317
|
+
userId: string,
|
|
318
|
+
filter: ListArtifactsFilter = {},
|
|
319
|
+
isAdmin = false,
|
|
320
|
+
): ArtifactMeta[] {
|
|
321
|
+
const db = getDb()
|
|
322
|
+
const conditions: string[] = [`(expires_at IS NULL OR expires_at > $now)`]
|
|
323
|
+
const params: Record<string, string> = { $now: nowIso() }
|
|
324
|
+
|
|
325
|
+
if (filter.sessionId) {
|
|
326
|
+
conditions.push('session_id = $sessionId')
|
|
327
|
+
params.$sessionId = filter.sessionId
|
|
328
|
+
}
|
|
329
|
+
if (filter.teamId) {
|
|
330
|
+
conditions.push('team_id = $teamId')
|
|
331
|
+
params.$teamId = filter.teamId
|
|
332
|
+
}
|
|
333
|
+
|
|
334
|
+
let rows: ArtifactRow[] = []
|
|
335
|
+
try {
|
|
336
|
+
rows = db
|
|
337
|
+
.query(
|
|
338
|
+
`SELECT * FROM artifacts WHERE ${conditions.join(' AND ')}
|
|
339
|
+
ORDER BY updated_at DESC LIMIT 500`,
|
|
340
|
+
)
|
|
341
|
+
.all(params) as unknown as ArtifactRow[]
|
|
342
|
+
} catch (err) {
|
|
343
|
+
logError('[artifacts] listArtifactsForUser failed:', err)
|
|
344
|
+
return []
|
|
345
|
+
}
|
|
346
|
+
|
|
347
|
+
if (isAdmin) return rows.map(toMeta)
|
|
348
|
+
return rows
|
|
349
|
+
.filter(row => isArtifactVisibleToUser(row.id, userId, false))
|
|
350
|
+
.map(toMeta)
|
|
351
|
+
}
|
|
352
|
+
|
|
353
|
+
/** Delete all artifacts past their expires_at. Returns the removed count. */
|
|
354
|
+
export function cleanupExpiredArtifacts(): number {
|
|
355
|
+
try {
|
|
356
|
+
const result = getDb()
|
|
357
|
+
.query(
|
|
358
|
+
'DELETE FROM artifacts WHERE expires_at IS NOT NULL AND expires_at <= $now',
|
|
359
|
+
)
|
|
360
|
+
.run({ $now: nowIso() })
|
|
361
|
+
const removed = (result as unknown as { changes?: number }).changes ?? 0
|
|
362
|
+
if (removed > 0) log(`[artifacts] cleaned up ${removed} expired artifacts`)
|
|
363
|
+
return removed
|
|
364
|
+
} catch (err) {
|
|
365
|
+
logError('[artifacts] cleanupExpiredArtifacts failed:', err)
|
|
366
|
+
return 0
|
|
367
|
+
}
|
|
368
|
+
}
|
|
369
|
+
|
|
370
|
+
/** Typed error carrying an upstream-compatible code. */
|
|
371
|
+
export class ArtifactError extends Error {
|
|
372
|
+
code: string
|
|
373
|
+
constructor(code: string, message: string) {
|
|
374
|
+
super(message)
|
|
375
|
+
this.name = 'ArtifactError'
|
|
376
|
+
this.code = code
|
|
377
|
+
}
|
|
378
|
+
}
|
|
@@ -277,6 +277,31 @@ export function updatePollTime(envId: string) {
|
|
|
277
277
|
storeUpdateEnvironment(envId, { lastPollAt: new Date() })
|
|
278
278
|
}
|
|
279
279
|
|
|
280
|
+
/**
|
|
281
|
+
* Worker-traffic liveness signal: refresh lastPollAt and, when the disconnect
|
|
282
|
+
* monitor had flipped the env to 'disconnected', reactivate it.
|
|
283
|
+
*
|
|
284
|
+
* The flip is based on a stale heartbeat — a worker actively hitting the env
|
|
285
|
+
* (work poll, assignment poll, session-creation retry during claim wait)
|
|
286
|
+
* proves it is alive. Without reactivation the CLI polls a zombie env
|
|
287
|
+
* forever: the work-poll route never 404s, so the client's env-lost recovery
|
|
288
|
+
* never fires, and any session created on the flipped env gets no work item
|
|
289
|
+
* (createWorkItem rejects non-active envs) — a session that exists but can
|
|
290
|
+
* never connect. 'deregistered' is terminal and stays dead.
|
|
291
|
+
*/
|
|
292
|
+
export function touchEnvironmentActivity(envId: string) {
|
|
293
|
+
const env = storeGetEnvironment(envId)
|
|
294
|
+
if (!env) return
|
|
295
|
+
if (env.status === 'disconnected') {
|
|
296
|
+
storeUpdateEnvironment(envId, { status: 'active', lastPollAt: new Date() })
|
|
297
|
+
log(
|
|
298
|
+
`[RCS] Environment ${envId} reactivated by worker traffic (was disconnected)`,
|
|
299
|
+
)
|
|
300
|
+
} else if (env.status === 'active') {
|
|
301
|
+
storeUpdateEnvironment(envId, { lastPollAt: new Date() })
|
|
302
|
+
}
|
|
303
|
+
}
|
|
304
|
+
|
|
280
305
|
export function listActiveEnvironments() {
|
|
281
306
|
return storeListActiveEnvironments()
|
|
282
307
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{e as d,j as e}from"./vendor-DE_-CLIE.js";import{
|
|
1
|
+
import{e as d,j as e}from"./vendor-DE_-CLIE.js";import{aq as c,ar as o,Q as m,al as s,ae as l,x as u}from"./main-B8hkVvfg.js";import"./shiki-mEP5vQQu.js";import"./motion-BILbV7YQ.js";function j(){c();const[a,i]=d.useState([]),{myTeams:r,isLoading:x}=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,")"]}),x?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,6 @@
|
|
|
1
|
+
import{e as r,j as e}from"./vendor-DE_-CLIE.js";import{ab as y,aq as b,V as j,al as s,K as N,aa as v,z as w}from"./main-B8hkVvfg.js";import{C as g}from"./copy-BD6qrRfd.js";import{E as k}from"./external-link-J-x6ty1h.js";import"./shiki-mEP5vQQu.js";import"./motion-BILbV7YQ.js";/**
|
|
2
|
+
* @license lucide-react v0.555.0 - ISC
|
|
3
|
+
*
|
|
4
|
+
* This source code is licensed under the ISC license.
|
|
5
|
+
* See the LICENSE file in the root directory of this source tree.
|
|
6
|
+
*/const C=[["path",{d:"M3 12a9 9 0 0 1 9-9 9.75 9.75 0 0 1 6.74 2.74L21 8",key:"v9h5vc"}],["path",{d:"M21 3v5h-5",key:"1q7to0"}],["path",{d:"M21 12a9 9 0 0 1-9 9 9.75 9.75 0 0 1-6.74-2.74L3 16",key:"3uifl3"}],["path",{d:"M8 16H3v5",key:"1cv678"}]],_=y("refresh-cw",C);function A({artifactId:i,onBack:c}){b();const[t,x]=r.useState(null),[n,d]=r.useState(""),[m,o]=r.useState(!1),[p,u]=r.useState(0);r.useEffect(()=>{let a=!1;return j(i).then(l=>{a||x(l)}).catch(l=>{a||d(l instanceof Error?l.message:s("artifacts.viewNotFound"))}),()=>{a=!0}},[i]);const f=r.useCallback(async()=>{if(window.confirm(s("artifacts.delete")+" — "+i.slice(0,8)+"…?"))try{await N(i),c()}catch(a){alert(a instanceof Error?a.message:s("artifacts.deleteFailed"))}},[i,c]),h=r.useCallback(async()=>{if(!t)return;await v(`${window.location.origin}${t.url}`)&&(o(!0),setTimeout(()=>o(!1),1500))},[t]);return n?e.jsx("div",{className:"flex flex-1 items-center justify-center",children:e.jsxs("div",{className:"text-center",children:[e.jsx("p",{className:"text-status-error",children:s("artifacts.viewNotFound")}),e.jsx("p",{className:"mt-1 text-xs text-text-muted",children:n}),e.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:s("artifacts.backToGallery")})]})}):t?e.jsxs("div",{className:"flex h-full min-h-0 flex-col",children:[e.jsxs("div",{className:"flex flex-wrap items-center gap-2 border-b border-border bg-surface-1 px-4 py-2.5",children:[e.jsx("button",{type:"button",onClick:c,className:"text-sm text-text-muted hover:text-text-primary",children:s("artifacts.backToGallery")}),e.jsx("span",{className:"text-text-muted/40",children:"/"}),e.jsx("span",{className:"truncate font-medium text-text-primary",children:t.title||t.id.slice(0,12)}),e.jsxs("span",{className:"rounded-full bg-surface-3 px-2 py-0.5 text-[11px] text-text-muted",children:["v",t.version]}),t.session_id&&e.jsxs("a",{href:`/code/${t.session_id}`,className:"truncate font-mono text-[11px] text-text-muted hover:text-accent",title:t.session_id,children:[s("artifacts.session"),": ",t.session_id.slice(0,14),"…"]}),t.expires_at&&e.jsxs("span",{className:"text-[11px] text-text-muted",title:t.expires_at,children:[s("artifacts.expires"),": ",new Date(t.expires_at).toLocaleDateString()]}),e.jsxs("div",{className:"ml-auto flex items-center gap-1",children:[e.jsx("button",{type:"button",onClick:()=>u(a=>a+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:s("common.loading"),children:e.jsx(_,{className:"h-3.5 w-3.5"})}),e.jsxs("button",{type:"button",onClick:h,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:s("artifacts.copyLink"),children:[e.jsx(g,{className:"h-3.5 w-3.5"}),m&&e.jsx("span",{className:"text-status-active",children:s("artifacts.copied")})]}),e.jsx("a",{href:t.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:s("artifacts.openInNewTab"),children:e.jsx(k,{className:"h-3.5 w-3.5"})}),e.jsx("button",{type:"button",onClick:f,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:s("artifacts.delete"),children:e.jsx(w,{className:"h-3.5 w-3.5"})})]})]}),e.jsx("iframe",{src:`${t.url}${t.url.includes("?")?"&":"?"}_=${Date.now()}`,title:t.title||t.id,className:"min-h-0 w-full flex-1 border-0 bg-white",sandbox:"allow-scripts allow-popups allow-forms"},p)]}):e.jsx("div",{className:"flex flex-1 items-center justify-center text-text-muted",children:s("common.loading")})}export{A as ArtifactView};
|