@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
|
@@ -13,6 +13,7 @@ import { createWorkItem } from '../../services/work-dispatch'
|
|
|
13
13
|
import { publishSessionEvent } from '../../services/transport'
|
|
14
14
|
import { loadPersistedEvents } from '../../services/event-persistence'
|
|
15
15
|
import { getEventBus } from '../../transport/event-bus'
|
|
16
|
+
import { touchEnvironmentActivity } from '../../services/environment'
|
|
16
17
|
import { acceptCliHeaders, apiKeyAuth } from '../../auth/middleware'
|
|
17
18
|
import {
|
|
18
19
|
bridgeAuth,
|
|
@@ -157,6 +158,19 @@ app.post('/', acceptCliHeaders, apiKeyAuth, async c => {
|
|
|
157
158
|
const body = await c.req.json()
|
|
158
159
|
const username = c.get('userId')
|
|
159
160
|
|
|
161
|
+
// Worker liveness: this route is the claim-wait loop's only traffic (an
|
|
162
|
+
// unowned env retries POST /v1/sessions every 5s until the claim URL is
|
|
163
|
+
// opened, up to 24h). Without touching the env here the disconnect monitor
|
|
164
|
+
// flips it to 'disconnected' after RCS_DISCONNECT_TIMEOUT, and when the
|
|
165
|
+
// claim finally lands the session is created but createWorkItem rejects
|
|
166
|
+
// the non-active env — a session that exists yet never receives work, so
|
|
167
|
+
// the CLI polls 204s forever and never connects. Touch BEFORE the unowned
|
|
168
|
+
// 409 so the retry loop itself keeps the env alive; touchEnvironmentActivity
|
|
169
|
+
// also reactivates an env the monitor already flipped.
|
|
170
|
+
if (typeof body.environment_id === 'string' && body.environment_id) {
|
|
171
|
+
touchEnvironmentActivity(body.environment_id)
|
|
172
|
+
}
|
|
173
|
+
|
|
160
174
|
// Resolve env ownership to bind session_owners.
|
|
161
175
|
let envOwnerUserId: string | null = null
|
|
162
176
|
let envTeamId: string | null = null
|
|
@@ -439,18 +453,34 @@ async function performAttach(
|
|
|
439
453
|
// owns (the env it just registered). Admin may attach on behalf.
|
|
440
454
|
const ownership = storeGetEnvironmentOwnership(envId)
|
|
441
455
|
if (!ownership?.ownerUserId) {
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
|
|
456
|
+
// The documented self-hosted worker setup authenticates with a bare
|
|
457
|
+
// RCS_API_KEYS admin key (SALUZI_BRIDGE_OAUTH_TOKEN, no
|
|
458
|
+
// SALUZI_BRIDGE_USERNAME) — its env is unowned until claimed, so a hard
|
|
459
|
+
// 409 here made `/rc --attach <id>` fail out of the box with a claim URL
|
|
460
|
+
// the direct-attach path never prints. Bare admin keys are trusted
|
|
461
|
+
// credentials (ensureAttachAccess already audited their session-manage
|
|
462
|
+
// bypass) — allow the bind. Identity callers still get the claim-flow
|
|
463
|
+
// guidance (the wait-mode CLI prints the URL).
|
|
464
|
+
if (!caller.isApiAdmin || caller.hasIdentity) {
|
|
465
|
+
return c.json(
|
|
466
|
+
{
|
|
467
|
+
error: {
|
|
468
|
+
type: 'environment_unowned',
|
|
469
|
+
message:
|
|
470
|
+
'Environment has no owner yet; claim it via the printed URL before attaching sessions',
|
|
471
|
+
},
|
|
448
472
|
},
|
|
449
|
-
|
|
450
|
-
|
|
473
|
+
409,
|
|
474
|
+
)
|
|
475
|
+
}
|
|
476
|
+
log(
|
|
477
|
+
`[audit] Bare admin API key attached session ${sessionId} to unowned env ${envId}`,
|
|
451
478
|
)
|
|
452
479
|
}
|
|
453
|
-
|
|
480
|
+
// Optional chain: the bare-admin fallthrough above leaves ownership
|
|
481
|
+
// possibly-null/unowned here — but isApiAdmin is true on that path, so the
|
|
482
|
+
// short-circuit keeps the semantics identical.
|
|
483
|
+
if (!caller.isApiAdmin && ownership?.ownerUserId !== caller.uuid) {
|
|
454
484
|
return c.json(
|
|
455
485
|
{
|
|
456
486
|
error: {
|
|
@@ -0,0 +1,249 @@
|
|
|
1
|
+
import { Hono } from 'hono'
|
|
2
|
+
import { getDb } from '../../db/sqlite'
|
|
3
|
+
import { sessionAuth } from '../../auth/middleware'
|
|
4
|
+
import { SYSTEM_USER_ID } from '../../auth/constants'
|
|
5
|
+
import { isSessionVisibleToUser } from '../../services/session'
|
|
6
|
+
import {
|
|
7
|
+
ArtifactError,
|
|
8
|
+
ARTIFACT_ALLOWED_TTLS,
|
|
9
|
+
canManageArtifact,
|
|
10
|
+
createArtifact,
|
|
11
|
+
deleteArtifact,
|
|
12
|
+
getArtifactRow,
|
|
13
|
+
isArtifactVisibleToUser,
|
|
14
|
+
listArtifactsForUser,
|
|
15
|
+
type ArtifactTtl,
|
|
16
|
+
} from '../../services/artifacts'
|
|
17
|
+
|
|
18
|
+
const app = new Hono()
|
|
19
|
+
|
|
20
|
+
/**
|
|
21
|
+
* Web-UI artifact routes (mounted under /web with CSRF protection).
|
|
22
|
+
*
|
|
23
|
+
* - GET /web/artifacts — artifacts visible to the caller
|
|
24
|
+
* (optionally filtered by ?session_id= / ?team_id=)
|
|
25
|
+
* - POST /web/artifacts — create from the gallery editor
|
|
26
|
+
* - GET /web/artifacts/:id — metadata (visibility-checked)
|
|
27
|
+
* - DELETE /web/artifacts/:id — remove (creator / session owner / team admin)
|
|
28
|
+
*/
|
|
29
|
+
|
|
30
|
+
/** Team membership check reused for ?team_id= filtering. */
|
|
31
|
+
function isTeamMember(
|
|
32
|
+
userId: string,
|
|
33
|
+
teamId: string,
|
|
34
|
+
db: ReturnType<typeof getDb>,
|
|
35
|
+
): boolean {
|
|
36
|
+
const row = db
|
|
37
|
+
.query(
|
|
38
|
+
'SELECT 1 FROM team_members WHERE team_id = $teamId AND user_id = $userId',
|
|
39
|
+
)
|
|
40
|
+
.get({ $teamId: teamId, $userId: userId })
|
|
41
|
+
return !!row
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
type ArtifactResponseRow = {
|
|
45
|
+
id: string
|
|
46
|
+
session_id: string | null
|
|
47
|
+
team_id: string | null
|
|
48
|
+
title: string | null
|
|
49
|
+
content_type: string
|
|
50
|
+
size: number
|
|
51
|
+
version: number
|
|
52
|
+
created_by: string | null
|
|
53
|
+
created_at: string
|
|
54
|
+
updated_at: string
|
|
55
|
+
expires_at: string | null
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
function toResponse(row: ArtifactResponseRow) {
|
|
59
|
+
return {
|
|
60
|
+
id: row.id,
|
|
61
|
+
session_id: row.session_id,
|
|
62
|
+
team_id: row.team_id,
|
|
63
|
+
title: row.title,
|
|
64
|
+
content_type: row.content_type,
|
|
65
|
+
size: row.size,
|
|
66
|
+
version: row.version,
|
|
67
|
+
created_by: row.created_by,
|
|
68
|
+
created_at: row.created_at,
|
|
69
|
+
updated_at: row.updated_at,
|
|
70
|
+
expires_at: row.expires_at,
|
|
71
|
+
url: `/v1/artifacts/${row.id}/content`,
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
app.get('/artifacts', sessionAuth, async c => {
|
|
76
|
+
const userId = c.get('userId') as string
|
|
77
|
+
const isAdmin = (c.get('isAdmin') as boolean) || userId === SYSTEM_USER_ID
|
|
78
|
+
const db = getDb()
|
|
79
|
+
|
|
80
|
+
const sessionId = c.req.query('session_id')
|
|
81
|
+
const teamId = c.req.query('team_id')
|
|
82
|
+
|
|
83
|
+
// Explicit filters narrow the result set but must not leak cross-team rows.
|
|
84
|
+
if (sessionId) {
|
|
85
|
+
if (!isAdmin && !isSessionVisibleToUser(sessionId, userId, db)) {
|
|
86
|
+
return c.json(
|
|
87
|
+
{
|
|
88
|
+
error: {
|
|
89
|
+
type: 'forbidden',
|
|
90
|
+
message: 'Not authorized for this session',
|
|
91
|
+
},
|
|
92
|
+
},
|
|
93
|
+
403,
|
|
94
|
+
)
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
if (teamId) {
|
|
98
|
+
if (!isAdmin && !isTeamMember(userId, teamId, db)) {
|
|
99
|
+
return c.json(
|
|
100
|
+
{ error: { type: 'forbidden', message: 'Not a member of this team' } },
|
|
101
|
+
403,
|
|
102
|
+
)
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
const rows = listArtifactsForUser(userId, { sessionId, teamId }, isAdmin)
|
|
107
|
+
return c.json(
|
|
108
|
+
rows.map(row => toResponse(row)),
|
|
109
|
+
200,
|
|
110
|
+
)
|
|
111
|
+
})
|
|
112
|
+
|
|
113
|
+
app.get('/artifacts/:id', sessionAuth, async c => {
|
|
114
|
+
const userId = c.get('userId') as string
|
|
115
|
+
const isAdmin = (c.get('isAdmin') as boolean) || userId === SYSTEM_USER_ID
|
|
116
|
+
const id = c.req.param('id')!
|
|
117
|
+
|
|
118
|
+
const row = getArtifactRow(id)
|
|
119
|
+
if (!row) {
|
|
120
|
+
return c.json(
|
|
121
|
+
{ error: { type: 'not_found', message: 'Artifact not found' } },
|
|
122
|
+
404,
|
|
123
|
+
)
|
|
124
|
+
}
|
|
125
|
+
if (!isArtifactVisibleToUser(id, userId, isAdmin)) {
|
|
126
|
+
return c.json(
|
|
127
|
+
{
|
|
128
|
+
error: {
|
|
129
|
+
type: 'forbidden',
|
|
130
|
+
message: 'Not authorized for this artifact',
|
|
131
|
+
},
|
|
132
|
+
},
|
|
133
|
+
403,
|
|
134
|
+
)
|
|
135
|
+
}
|
|
136
|
+
return c.json(toResponse(row), 200)
|
|
137
|
+
})
|
|
138
|
+
|
|
139
|
+
app.post('/artifacts', sessionAuth, async c => {
|
|
140
|
+
const userId = c.get('userId') as string
|
|
141
|
+
|
|
142
|
+
let body: Record<string, unknown>
|
|
143
|
+
try {
|
|
144
|
+
body = await c.req.json()
|
|
145
|
+
} catch {
|
|
146
|
+
return c.json(
|
|
147
|
+
{ error: { type: 'bad_request', message: 'Invalid JSON' } },
|
|
148
|
+
400,
|
|
149
|
+
)
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
const html = typeof body.html === 'string' ? body.html : ''
|
|
153
|
+
if (!html.trim()) {
|
|
154
|
+
return c.json(
|
|
155
|
+
{ error: { type: 'bad_request', message: 'html is required' } },
|
|
156
|
+
400,
|
|
157
|
+
)
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
const title =
|
|
161
|
+
typeof body.title === 'string' && body.title.trim()
|
|
162
|
+
? body.title.trim()
|
|
163
|
+
: undefined
|
|
164
|
+
|
|
165
|
+
let ttl: ArtifactTtl | undefined
|
|
166
|
+
if (body.ttl !== undefined) {
|
|
167
|
+
const n =
|
|
168
|
+
typeof body.ttl === 'number'
|
|
169
|
+
? body.ttl
|
|
170
|
+
: Number.parseInt(String(body.ttl), 10)
|
|
171
|
+
if (!ARTIFACT_ALLOWED_TTLS.includes(n as ArtifactTtl)) {
|
|
172
|
+
return c.json(
|
|
173
|
+
{ error: { type: 'bad_request', message: 'ttl must be 7 or 30' } },
|
|
174
|
+
400,
|
|
175
|
+
)
|
|
176
|
+
}
|
|
177
|
+
ttl = n as ArtifactTtl
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
// Optional session binding — caller must be able to see the session.
|
|
181
|
+
let sessionId: string | undefined
|
|
182
|
+
if (typeof body.session_id === 'string' && body.session_id) {
|
|
183
|
+
const db = getDb()
|
|
184
|
+
if (!isSessionVisibleToUser(body.session_id, userId, db)) {
|
|
185
|
+
return c.json(
|
|
186
|
+
{
|
|
187
|
+
error: {
|
|
188
|
+
type: 'forbidden',
|
|
189
|
+
message: 'Not authorized for this session',
|
|
190
|
+
},
|
|
191
|
+
},
|
|
192
|
+
403,
|
|
193
|
+
)
|
|
194
|
+
}
|
|
195
|
+
sessionId = body.session_id
|
|
196
|
+
}
|
|
197
|
+
|
|
198
|
+
try {
|
|
199
|
+
const result = createArtifact({
|
|
200
|
+
html,
|
|
201
|
+
ttl,
|
|
202
|
+
sessionId,
|
|
203
|
+
title,
|
|
204
|
+
createdBy: userId,
|
|
205
|
+
})
|
|
206
|
+
const row = getArtifactRow(result.id)
|
|
207
|
+
return c.json(
|
|
208
|
+
row
|
|
209
|
+
? toResponse(row)
|
|
210
|
+
: { id: result.id, expires_at: result.expiresAt },
|
|
211
|
+
201,
|
|
212
|
+
)
|
|
213
|
+
} catch (err) {
|
|
214
|
+
if (err instanceof ArtifactError) {
|
|
215
|
+
const status = err.code === 'payload_too_large' ? 413 : 400
|
|
216
|
+
return c.json({ error: { type: err.code, message: err.message } }, status)
|
|
217
|
+
}
|
|
218
|
+
throw err
|
|
219
|
+
}
|
|
220
|
+
})
|
|
221
|
+
|
|
222
|
+
app.delete('/artifacts/:id', sessionAuth, async c => {
|
|
223
|
+
const userId = c.get('userId') as string
|
|
224
|
+
const isAdmin = (c.get('isAdmin') as boolean) || userId === SYSTEM_USER_ID
|
|
225
|
+
const id = c.req.param('id')!
|
|
226
|
+
|
|
227
|
+
if (!getArtifactRow(id)) {
|
|
228
|
+
return c.json(
|
|
229
|
+
{ error: { type: 'not_found', message: 'Artifact not found' } },
|
|
230
|
+
404,
|
|
231
|
+
)
|
|
232
|
+
}
|
|
233
|
+
if (!canManageArtifact(id, userId, isAdmin)) {
|
|
234
|
+
return c.json(
|
|
235
|
+
{
|
|
236
|
+
error: {
|
|
237
|
+
type: 'forbidden',
|
|
238
|
+
message: 'Not authorized to delete this artifact',
|
|
239
|
+
},
|
|
240
|
+
},
|
|
241
|
+
403,
|
|
242
|
+
)
|
|
243
|
+
}
|
|
244
|
+
|
|
245
|
+
deleteArtifact(id)
|
|
246
|
+
return c.json({ ok: true }, 200)
|
|
247
|
+
})
|
|
248
|
+
|
|
249
|
+
export default app
|
|
@@ -96,6 +96,31 @@ app.post('/sessions', sessionAuth, async c => {
|
|
|
96
96
|
const session = getSession(sessionId)
|
|
97
97
|
return c.json(toWebSessionResponse(session!), 200)
|
|
98
98
|
}
|
|
99
|
+
|
|
100
|
+
// In-process (replBridge) workers register with workerType='repl' and
|
|
101
|
+
// maxSessions=1 — they can only serve one session at a time. Reject
|
|
102
|
+
// multi-session creation with a helpful error guiding the user to
|
|
103
|
+
// `slz rc` (spawn mode). MUST run before createSession: the new session
|
|
104
|
+
// is created WITH body.environment_id, so checking after would always
|
|
105
|
+
// see the just-created session and 409 every request (leaving a stray
|
|
106
|
+
// bound-but-never-dispatched session behind on each retry).
|
|
107
|
+
if (env?.workerType === 'repl') {
|
|
108
|
+
const existing = storeListSessionsByEnvironment(env.id).filter(
|
|
109
|
+
s => !isSessionClosedStatus(s.status),
|
|
110
|
+
)
|
|
111
|
+
if (existing.length > 0) {
|
|
112
|
+
return c.json(
|
|
113
|
+
{
|
|
114
|
+
error: {
|
|
115
|
+
type: 'worker_at_capacity',
|
|
116
|
+
message:
|
|
117
|
+
'该 worker 为 in-process 模式(slz 默认),只支持单会话。请用 `slz rc` 启动 spawn 模式 worker 支持多会话。',
|
|
118
|
+
},
|
|
119
|
+
},
|
|
120
|
+
409,
|
|
121
|
+
)
|
|
122
|
+
}
|
|
123
|
+
}
|
|
99
124
|
}
|
|
100
125
|
|
|
101
126
|
const teamId = typeof body.team_id === 'string' ? body.team_id : null
|
|
@@ -120,28 +145,6 @@ app.post('/sessions', sessionAuth, async c => {
|
|
|
120
145
|
|
|
121
146
|
// Dispatch work to environment if specified
|
|
122
147
|
if (body.environment_id) {
|
|
123
|
-
// In-process (replBridge) workers register with workerType='repl' and
|
|
124
|
-
// maxSessions=1 — they can only serve one session at a time. Reject
|
|
125
|
-
// multi-session creation with a helpful error guiding the user to
|
|
126
|
-
// `slz rc` (spawn mode).
|
|
127
|
-
const env = storeGetEnvironment(body.environment_id)
|
|
128
|
-
if (env?.workerType === 'repl') {
|
|
129
|
-
const existing = storeListSessionsByEnvironment(env.id).filter(
|
|
130
|
-
s => !isSessionClosedStatus(s.status),
|
|
131
|
-
)
|
|
132
|
-
if (existing.length > 0) {
|
|
133
|
-
return c.json(
|
|
134
|
-
{
|
|
135
|
-
error: {
|
|
136
|
-
type: 'worker_at_capacity',
|
|
137
|
-
message:
|
|
138
|
-
'该 worker 为 in-process 模式(slz 默认),只支持单会话。请用 `slz rc` 启动 spawn 模式 worker 支持多会话。',
|
|
139
|
-
},
|
|
140
|
-
},
|
|
141
|
-
409,
|
|
142
|
-
)
|
|
143
|
-
}
|
|
144
|
-
}
|
|
145
148
|
try {
|
|
146
149
|
const spawnMode =
|
|
147
150
|
body.spawn_mode === 'worktree' || body.spawn_mode === 'same-dir'
|