@saluzi/saluzi-edu 0.2.62 → 0.2.64
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 +179 -179
- package/dist/guide/guide-data.json +12 -0
- package/dist/rcs-schema.sql +2 -1
- package/dist/rcs-web/assets/{AdminPanel-Xlza8Stt.js → AdminPanel-CqP_94xa.js} +1 -1
- package/{packages/remote-control-server/web/dist/assets/Claim-BMWwu213.js → dist/rcs-web/assets/Claim-BvfARQ6Q.js} +1 -1
- package/{packages/remote-control-server/web/dist/assets/Dashboard-D5awDzM3.js → dist/rcs-web/assets/Dashboard-BDGi4XpN.js} +1 -1
- package/{packages/remote-control-server/web/dist/assets/Join-ok37ggfZ.js → dist/rcs-web/assets/Join-PPDYBhsJ.js} +1 -1
- package/dist/rcs-web/assets/{Login-5qo97rq-.js → Login-JprQIEpr.js} +1 -1
- package/dist/rcs-web/assets/{Register-D_UOG8ar.js → Register-cuGuAE83.js} +1 -1
- package/dist/rcs-web/assets/{SessionDetail-BbHrR4Qu.js → SessionDetail-D-xhkyLo.js} +5 -5
- package/dist/rcs-web/assets/{SessionVisibilityBadge-Dy4FwTzo.js → SessionVisibilityBadge-91WyR9K6.js} +1 -1
- package/dist/rcs-web/assets/{Setup-GnPeNyH9.js → Setup-Buwa9Y3M.js} +1 -1
- package/dist/rcs-web/assets/{ShareLanding-CUjQydLL.js → ShareLanding-DhwgJb6V.js} +1 -1
- package/dist/rcs-web/assets/{TeamCreate-Ck2fEoUW.js → TeamCreate-CaoinTSG.js} +1 -1
- package/dist/rcs-web/assets/{TeamDetail-De6EPND0.js → TeamDetail-D5ahen24.js} +1 -1
- package/dist/rcs-web/assets/{TeamList-C-0LJRxd.js → TeamList-qCuKKSH3.js} +1 -1
- package/dist/rcs-web/assets/{TeamSettings-BszOrXVW.js → TeamSettings-BaIwImrp.js} +1 -1
- package/dist/rcs-web/assets/{UserSearchInput-CyQWtLL-.js → UserSearchInput-BxcYR_HU.js} +1 -1
- package/dist/rcs-web/assets/{UserSettings-DgyYp-1y.js → UserSettings-zfGfcuWs.js} +1 -1
- package/dist/rcs-web/assets/{arc-BaOPt7k-.js → arc-DwAbF6eM.js} +1 -1
- package/dist/rcs-web/assets/{architectureDiagram-3BPJPVTR-SvIakXbT.js → architectureDiagram-3BPJPVTR-uMOwOwiN.js} +1 -1
- package/{packages/remote-control-server/web/dist/assets/blockDiagram-GPEHLZMM-CiDp9J7i.js → dist/rcs-web/assets/blockDiagram-GPEHLZMM-B5BqFTkP.js} +1 -1
- package/dist/rcs-web/assets/{c4Diagram-AAUBKEIU-D9wzA9ur.js → c4Diagram-AAUBKEIU-D6eienz2.js} +1 -1
- package/dist/rcs-web/assets/channel-CCfqpGSl.js +1 -0
- package/dist/rcs-web/assets/{chunk-2J33WTMH-qfYueRAP.js → chunk-2J33WTMH-DqVxv8yW.js} +1 -1
- package/dist/rcs-web/assets/{chunk-4BX2VUAB-D1V_UCiK.js → chunk-4BX2VUAB-X5o4x8om.js} +1 -1
- package/dist/rcs-web/assets/{chunk-55IACEB6-C67QiGmo.js → chunk-55IACEB6-D7G25_Y5.js} +1 -1
- package/{packages/remote-control-server/web/dist/assets/chunk-727SXJPM-D2Wln4TT.js → dist/rcs-web/assets/chunk-727SXJPM-CoXI1FIy.js} +1 -1
- package/dist/rcs-web/assets/{chunk-AQP2D5EJ-03h8hZhw.js → chunk-AQP2D5EJ-C73Crhqe.js} +1 -1
- package/dist/rcs-web/assets/{chunk-FMBD7UC4-7zas8pDp.js → chunk-FMBD7UC4-DVzxIsSE.js} +1 -1
- package/dist/rcs-web/assets/{chunk-ND2GUHAM-PUXucyY6.js → chunk-ND2GUHAM-C6_oEhLf.js} +1 -1
- package/dist/rcs-web/assets/{chunk-QZHKN3VN-M3U5l4yW.js → chunk-QZHKN3VN-COvH7k5r.js} +1 -1
- package/dist/rcs-web/assets/classDiagram-4FO5ZUOK-DzNdVs3v.js +1 -0
- package/dist/rcs-web/assets/classDiagram-v2-Q7XG4LA2-DzNdVs3v.js +1 -0
- package/dist/rcs-web/assets/{code-block-IT6T5CEO-BgUazuuS.js → code-block-IT6T5CEO-CE-2f_-K.js} +1 -1
- package/dist/rcs-web/assets/{copy-DjaSB1Rw.js → copy-9pzb1Po6.js} +1 -1
- package/dist/rcs-web/assets/{cose-bilkent-S5V4N54A-zPupX74N.js → cose-bilkent-S5V4N54A-B9sMDFRe.js} +1 -1
- package/dist/rcs-web/assets/{dagre-BM42HDAG-B_EJ050J.js → dagre-BM42HDAG-DB1jXylM.js} +1 -1
- package/dist/rcs-web/assets/{diagram-2AECGRRQ-dnnxPH7w.js → diagram-2AECGRRQ-MNuqSRmg.js} +1 -1
- package/dist/rcs-web/assets/{diagram-5GNKFQAL-CLEOqCLZ.js → diagram-5GNKFQAL-BZwhvaEY.js} +1 -1
- package/dist/rcs-web/assets/{diagram-KO2AKTUF-DKBGpiRW.js → diagram-KO2AKTUF-3Wp2PnI2.js} +1 -1
- package/dist/rcs-web/assets/{diagram-LMA3HP47-BAilhXiA.js → diagram-LMA3HP47-CTcV1SBj.js} +1 -1
- package/dist/rcs-web/assets/{diagram-OG6HWLK6-C3CdmOxC.js → diagram-OG6HWLK6-DzXhSQDC.js} +1 -1
- package/dist/rcs-web/assets/{erDiagram-TEJ5UH35-D1yv-3Jv.js → erDiagram-TEJ5UH35-CwSihkB8.js} +1 -1
- package/dist/rcs-web/assets/{flowDiagram-I6XJVG4X-DpW11XWj.js → flowDiagram-I6XJVG4X-BSuXctT4.js} +1 -1
- package/{packages/remote-control-server/web/dist/assets/ganttDiagram-6RSMTGT7-CWr8suZm.js → dist/rcs-web/assets/ganttDiagram-6RSMTGT7-B87oxjmY.js} +1 -1
- package/dist/rcs-web/assets/{gitGraphDiagram-PVQCEYII-BspxLSNV.js → gitGraphDiagram-PVQCEYII-BRrwOi3C.js} +1 -1
- package/dist/rcs-web/assets/{infoDiagram-5YYISTIA-Bow20s-Q.js → infoDiagram-5YYISTIA-B-8QXS0n.js} +1 -1
- package/dist/rcs-web/assets/{ishikawaDiagram-YF4QCWOH-BESvGYGI.js → ishikawaDiagram-YF4QCWOH-Bau9MU6C.js} +1 -1
- package/dist/rcs-web/assets/{journeyDiagram-JHISSGLW-DZ6gzC7H.js → journeyDiagram-JHISSGLW-D_tAp--R.js} +1 -1
- package/dist/rcs-web/assets/{kanban-definition-UN3LZRKU-DIQo2GiM.js → kanban-definition-UN3LZRKU---UIvjMZ.js} +1 -1
- package/dist/rcs-web/assets/{linear-CdXALiZ8.js → linear-CIDLjd5h.js} +1 -1
- package/dist/rcs-web/assets/{main-CwLwGVDc.js → main-N3GYCdLF.js} +3 -3
- package/dist/rcs-web/assets/{mermaid-VLURNSYL-C0ZKM74W.js → mermaid-VLURNSYL-Cu5A5sMk.js} +4 -4
- package/dist/rcs-web/assets/{mermaid.core-eEtoQhrQ.js → mermaid.core-CEJOtCGw.js} +5 -5
- package/dist/rcs-web/assets/{mindmap-definition-RKZ34NQL-CcW3H_cH.js → mindmap-definition-RKZ34NQL-ldyccyCP.js} +1 -1
- package/dist/rcs-web/assets/{pieDiagram-4H26LBE5-DpXUpJMl.js → pieDiagram-4H26LBE5-CmghofeF.js} +1 -1
- package/{packages/remote-control-server/web/dist/assets/quadrantDiagram-W4KKPZXB-DOwMRzzP.js → dist/rcs-web/assets/quadrantDiagram-W4KKPZXB-B-2N2UHr.js} +1 -1
- package/dist/rcs-web/assets/{requirementDiagram-4Y6WPE33-CBi_6NcW.js → requirementDiagram-4Y6WPE33-39jlO9Y8.js} +1 -1
- package/{packages/remote-control-server/web/dist/assets/sankeyDiagram-5OEKKPKP-CKbAoTHm.js → dist/rcs-web/assets/sankeyDiagram-5OEKKPKP-DdY7KNFB.js} +1 -1
- package/dist/rcs-web/assets/{sequenceDiagram-3UESZ5HK-a3rYCe-w.js → sequenceDiagram-3UESZ5HK-D2k5rX6x.js} +1 -1
- package/dist/rcs-web/assets/{stateDiagram-AJRCARHV-B6R_Dt84.js → stateDiagram-AJRCARHV-CP9N457o.js} +1 -1
- package/dist/rcs-web/assets/{stateDiagram-v2-BHNVJYJU-Cq935fvz.js → stateDiagram-v2-BHNVJYJU-CPhZYlL0.js} +1 -1
- package/{packages/remote-control-server/web/dist/assets/timeline-definition-PNZ67QCA-8DXPKq1k.js → dist/rcs-web/assets/timeline-definition-PNZ67QCA-DSEPBO8O.js} +1 -1
- package/dist/rcs-web/assets/{vennDiagram-CIIHVFJN-BfDEkku5.js → vennDiagram-CIIHVFJN-CkNMwCJ3.js} +1 -1
- package/dist/rcs-web/assets/{wardleyDiagram-YWT4CUSO-Dvp2XZVf.js → wardleyDiagram-YWT4CUSO-Cxd-F60s.js} +1 -1
- package/{packages/remote-control-server/web/dist/assets/xychartDiagram-2RQKCTM6-DiPjQLUx.js → dist/rcs-web/assets/xychartDiagram-2RQKCTM6-BLL105NN.js} +1 -1
- package/dist/rcs-web/index.html +1 -1
- package/package.json +1 -1
- package/packages/remote-control-server/src/__tests__/attach-code.test.ts +183 -0
- package/packages/remote-control-server/src/__tests__/attach-wait.test.ts +213 -0
- package/packages/remote-control-server/src/__tests__/attach.test.ts +521 -0
- package/packages/remote-control-server/src/__tests__/turn-end-status.test.ts +217 -1
- package/packages/remote-control-server/src/auth/bridge-auth.ts +76 -0
- package/packages/remote-control-server/src/db/rcs-schema.sql +2 -1
- package/packages/remote-control-server/src/db/sqlite.ts +1 -0
- package/packages/remote-control-server/src/routes/v1/environments.ts +48 -74
- package/packages/remote-control-server/src/routes/v1/sessions.ts +558 -4
- package/packages/remote-control-server/src/routes/v2/worker-events.ts +12 -1
- package/packages/remote-control-server/src/routes/web/control.ts +11 -2
- package/packages/remote-control-server/src/routes/web/sessions.ts +67 -0
- package/packages/remote-control-server/src/services/environment.ts +27 -0
- package/packages/remote-control-server/src/store.ts +107 -2
- package/packages/remote-control-server/src/transport/event-bus.ts +15 -0
- package/packages/remote-control-server/src/transport/ws-handler.ts +14 -1
- package/packages/remote-control-server/src/types/api.ts +2 -0
- package/packages/remote-control-server/web/dist/assets/{AdminPanel-Xlza8Stt.js → AdminPanel-CqP_94xa.js} +1 -1
- package/{dist/rcs-web/assets/Claim-BMWwu213.js → packages/remote-control-server/web/dist/assets/Claim-BvfARQ6Q.js} +1 -1
- package/{dist/rcs-web/assets/Dashboard-D5awDzM3.js → packages/remote-control-server/web/dist/assets/Dashboard-BDGi4XpN.js} +1 -1
- package/{dist/rcs-web/assets/Join-ok37ggfZ.js → packages/remote-control-server/web/dist/assets/Join-PPDYBhsJ.js} +1 -1
- package/packages/remote-control-server/web/dist/assets/{Login-5qo97rq-.js → Login-JprQIEpr.js} +1 -1
- package/packages/remote-control-server/web/dist/assets/{Register-D_UOG8ar.js → Register-cuGuAE83.js} +1 -1
- package/packages/remote-control-server/web/dist/assets/{SessionDetail-BbHrR4Qu.js → SessionDetail-D-xhkyLo.js} +5 -5
- package/packages/remote-control-server/web/dist/assets/{SessionVisibilityBadge-Dy4FwTzo.js → SessionVisibilityBadge-91WyR9K6.js} +1 -1
- package/packages/remote-control-server/web/dist/assets/{Setup-GnPeNyH9.js → Setup-Buwa9Y3M.js} +1 -1
- package/packages/remote-control-server/web/dist/assets/{ShareLanding-CUjQydLL.js → ShareLanding-DhwgJb6V.js} +1 -1
- package/packages/remote-control-server/web/dist/assets/{TeamCreate-Ck2fEoUW.js → TeamCreate-CaoinTSG.js} +1 -1
- package/packages/remote-control-server/web/dist/assets/{TeamDetail-De6EPND0.js → TeamDetail-D5ahen24.js} +1 -1
- package/packages/remote-control-server/web/dist/assets/{TeamList-C-0LJRxd.js → TeamList-qCuKKSH3.js} +1 -1
- package/packages/remote-control-server/web/dist/assets/{TeamSettings-BszOrXVW.js → TeamSettings-BaIwImrp.js} +1 -1
- package/packages/remote-control-server/web/dist/assets/{UserSearchInput-CyQWtLL-.js → UserSearchInput-BxcYR_HU.js} +1 -1
- package/packages/remote-control-server/web/dist/assets/{UserSettings-DgyYp-1y.js → UserSettings-zfGfcuWs.js} +1 -1
- package/packages/remote-control-server/web/dist/assets/{arc-BaOPt7k-.js → arc-DwAbF6eM.js} +1 -1
- package/packages/remote-control-server/web/dist/assets/{architectureDiagram-3BPJPVTR-SvIakXbT.js → architectureDiagram-3BPJPVTR-uMOwOwiN.js} +1 -1
- package/{dist/rcs-web/assets/blockDiagram-GPEHLZMM-CiDp9J7i.js → packages/remote-control-server/web/dist/assets/blockDiagram-GPEHLZMM-B5BqFTkP.js} +1 -1
- package/packages/remote-control-server/web/dist/assets/{c4Diagram-AAUBKEIU-D9wzA9ur.js → c4Diagram-AAUBKEIU-D6eienz2.js} +1 -1
- package/packages/remote-control-server/web/dist/assets/channel-CCfqpGSl.js +1 -0
- package/packages/remote-control-server/web/dist/assets/{chunk-2J33WTMH-qfYueRAP.js → chunk-2J33WTMH-DqVxv8yW.js} +1 -1
- package/packages/remote-control-server/web/dist/assets/{chunk-4BX2VUAB-D1V_UCiK.js → chunk-4BX2VUAB-X5o4x8om.js} +1 -1
- package/packages/remote-control-server/web/dist/assets/{chunk-55IACEB6-C67QiGmo.js → chunk-55IACEB6-D7G25_Y5.js} +1 -1
- package/{dist/rcs-web/assets/chunk-727SXJPM-D2Wln4TT.js → packages/remote-control-server/web/dist/assets/chunk-727SXJPM-CoXI1FIy.js} +1 -1
- package/packages/remote-control-server/web/dist/assets/{chunk-AQP2D5EJ-03h8hZhw.js → chunk-AQP2D5EJ-C73Crhqe.js} +1 -1
- package/packages/remote-control-server/web/dist/assets/{chunk-FMBD7UC4-7zas8pDp.js → chunk-FMBD7UC4-DVzxIsSE.js} +1 -1
- package/packages/remote-control-server/web/dist/assets/{chunk-ND2GUHAM-PUXucyY6.js → chunk-ND2GUHAM-C6_oEhLf.js} +1 -1
- package/packages/remote-control-server/web/dist/assets/{chunk-QZHKN3VN-M3U5l4yW.js → chunk-QZHKN3VN-COvH7k5r.js} +1 -1
- package/packages/remote-control-server/web/dist/assets/classDiagram-4FO5ZUOK-DzNdVs3v.js +1 -0
- package/packages/remote-control-server/web/dist/assets/classDiagram-v2-Q7XG4LA2-DzNdVs3v.js +1 -0
- package/packages/remote-control-server/web/dist/assets/{code-block-IT6T5CEO-BgUazuuS.js → code-block-IT6T5CEO-CE-2f_-K.js} +1 -1
- package/packages/remote-control-server/web/dist/assets/{copy-DjaSB1Rw.js → copy-9pzb1Po6.js} +1 -1
- package/packages/remote-control-server/web/dist/assets/{cose-bilkent-S5V4N54A-zPupX74N.js → cose-bilkent-S5V4N54A-B9sMDFRe.js} +1 -1
- package/packages/remote-control-server/web/dist/assets/{dagre-BM42HDAG-B_EJ050J.js → dagre-BM42HDAG-DB1jXylM.js} +1 -1
- package/packages/remote-control-server/web/dist/assets/{diagram-2AECGRRQ-dnnxPH7w.js → diagram-2AECGRRQ-MNuqSRmg.js} +1 -1
- package/packages/remote-control-server/web/dist/assets/{diagram-5GNKFQAL-CLEOqCLZ.js → diagram-5GNKFQAL-BZwhvaEY.js} +1 -1
- package/packages/remote-control-server/web/dist/assets/{diagram-KO2AKTUF-DKBGpiRW.js → diagram-KO2AKTUF-3Wp2PnI2.js} +1 -1
- package/packages/remote-control-server/web/dist/assets/{diagram-LMA3HP47-BAilhXiA.js → diagram-LMA3HP47-CTcV1SBj.js} +1 -1
- package/packages/remote-control-server/web/dist/assets/{diagram-OG6HWLK6-C3CdmOxC.js → diagram-OG6HWLK6-DzXhSQDC.js} +1 -1
- package/packages/remote-control-server/web/dist/assets/{erDiagram-TEJ5UH35-D1yv-3Jv.js → erDiagram-TEJ5UH35-CwSihkB8.js} +1 -1
- package/packages/remote-control-server/web/dist/assets/{flowDiagram-I6XJVG4X-DpW11XWj.js → flowDiagram-I6XJVG4X-BSuXctT4.js} +1 -1
- package/{dist/rcs-web/assets/ganttDiagram-6RSMTGT7-CWr8suZm.js → packages/remote-control-server/web/dist/assets/ganttDiagram-6RSMTGT7-B87oxjmY.js} +1 -1
- package/packages/remote-control-server/web/dist/assets/{gitGraphDiagram-PVQCEYII-BspxLSNV.js → gitGraphDiagram-PVQCEYII-BRrwOi3C.js} +1 -1
- package/packages/remote-control-server/web/dist/assets/{infoDiagram-5YYISTIA-Bow20s-Q.js → infoDiagram-5YYISTIA-B-8QXS0n.js} +1 -1
- package/packages/remote-control-server/web/dist/assets/{ishikawaDiagram-YF4QCWOH-BESvGYGI.js → ishikawaDiagram-YF4QCWOH-Bau9MU6C.js} +1 -1
- package/packages/remote-control-server/web/dist/assets/{journeyDiagram-JHISSGLW-DZ6gzC7H.js → journeyDiagram-JHISSGLW-D_tAp--R.js} +1 -1
- package/packages/remote-control-server/web/dist/assets/{kanban-definition-UN3LZRKU-DIQo2GiM.js → kanban-definition-UN3LZRKU---UIvjMZ.js} +1 -1
- package/packages/remote-control-server/web/dist/assets/{linear-CdXALiZ8.js → linear-CIDLjd5h.js} +1 -1
- package/packages/remote-control-server/web/dist/assets/{main-CwLwGVDc.js → main-N3GYCdLF.js} +3 -3
- package/packages/remote-control-server/web/dist/assets/{mermaid-VLURNSYL-C0ZKM74W.js → mermaid-VLURNSYL-Cu5A5sMk.js} +4 -4
- package/packages/remote-control-server/web/dist/assets/{mermaid.core-eEtoQhrQ.js → mermaid.core-CEJOtCGw.js} +5 -5
- package/packages/remote-control-server/web/dist/assets/{mindmap-definition-RKZ34NQL-CcW3H_cH.js → mindmap-definition-RKZ34NQL-ldyccyCP.js} +1 -1
- package/packages/remote-control-server/web/dist/assets/{pieDiagram-4H26LBE5-DpXUpJMl.js → pieDiagram-4H26LBE5-CmghofeF.js} +1 -1
- package/{dist/rcs-web/assets/quadrantDiagram-W4KKPZXB-DOwMRzzP.js → packages/remote-control-server/web/dist/assets/quadrantDiagram-W4KKPZXB-B-2N2UHr.js} +1 -1
- package/packages/remote-control-server/web/dist/assets/{requirementDiagram-4Y6WPE33-CBi_6NcW.js → requirementDiagram-4Y6WPE33-39jlO9Y8.js} +1 -1
- package/{dist/rcs-web/assets/sankeyDiagram-5OEKKPKP-CKbAoTHm.js → packages/remote-control-server/web/dist/assets/sankeyDiagram-5OEKKPKP-DdY7KNFB.js} +1 -1
- package/packages/remote-control-server/web/dist/assets/{sequenceDiagram-3UESZ5HK-a3rYCe-w.js → sequenceDiagram-3UESZ5HK-D2k5rX6x.js} +1 -1
- package/packages/remote-control-server/web/dist/assets/{stateDiagram-AJRCARHV-B6R_Dt84.js → stateDiagram-AJRCARHV-CP9N457o.js} +1 -1
- package/packages/remote-control-server/web/dist/assets/{stateDiagram-v2-BHNVJYJU-Cq935fvz.js → stateDiagram-v2-BHNVJYJU-CPhZYlL0.js} +1 -1
- package/{dist/rcs-web/assets/timeline-definition-PNZ67QCA-8DXPKq1k.js → packages/remote-control-server/web/dist/assets/timeline-definition-PNZ67QCA-DSEPBO8O.js} +1 -1
- package/packages/remote-control-server/web/dist/assets/{vennDiagram-CIIHVFJN-BfDEkku5.js → vennDiagram-CIIHVFJN-CkNMwCJ3.js} +1 -1
- package/packages/remote-control-server/web/dist/assets/{wardleyDiagram-YWT4CUSO-Dvp2XZVf.js → wardleyDiagram-YWT4CUSO-Cxd-F60s.js} +1 -1
- package/{dist/rcs-web/assets/xychartDiagram-2RQKCTM6-DiPjQLUx.js → packages/remote-control-server/web/dist/assets/xychartDiagram-2RQKCTM6-BLL105NN.js} +1 -1
- package/packages/remote-control-server/web/dist/index.html +1 -1
- package/dist/rcs-web/assets/channel-CirgRB_G.js +0 -1
- package/dist/rcs-web/assets/classDiagram-4FO5ZUOK-Cq12UEz9.js +0 -1
- package/dist/rcs-web/assets/classDiagram-v2-Q7XG4LA2-Cq12UEz9.js +0 -1
- package/packages/remote-control-server/web/dist/assets/channel-CirgRB_G.js +0 -1
- package/packages/remote-control-server/web/dist/assets/classDiagram-4FO5ZUOK-Cq12UEz9.js +0 -1
- package/packages/remote-control-server/web/dist/assets/classDiagram-v2-Q7XG4LA2-Cq12UEz9.js +0 -1
|
@@ -0,0 +1,213 @@
|
|
|
1
|
+
import { describe, test, expect, beforeEach, mock } from 'bun:test'
|
|
2
|
+
import { mockConfigModule } from './helpers/mock-config'
|
|
3
|
+
|
|
4
|
+
// Mock config before any module imports
|
|
5
|
+
mock.module('../config', () => mockConfigModule())
|
|
6
|
+
|
|
7
|
+
import { Hono } from 'hono'
|
|
8
|
+
import type { Database } from 'bun:sqlite'
|
|
9
|
+
import { randomUUID } from 'node:crypto'
|
|
10
|
+
import { tmpdir } from 'node:os'
|
|
11
|
+
import { resolve } from 'node:path'
|
|
12
|
+
import v1Environments from '../routes/v1/environments'
|
|
13
|
+
import webEnvironments from '../routes/web/environments'
|
|
14
|
+
import {
|
|
15
|
+
storeReset,
|
|
16
|
+
storeCreateEnvironment,
|
|
17
|
+
storeGetEnvironment,
|
|
18
|
+
storeUpdateEnvironment,
|
|
19
|
+
storeListActiveEnvironmentsWithTeam,
|
|
20
|
+
} from '../store'
|
|
21
|
+
import { initDatabase, resetDbSingleton, getDb } from '../db/sqlite'
|
|
22
|
+
import { issueSessionToken } from '../auth/session'
|
|
23
|
+
import { createUserDirectly } from './helpers/fixtures'
|
|
24
|
+
import { createSession, archiveSession } from '../services/session'
|
|
25
|
+
import { storeBindSession } from '../store'
|
|
26
|
+
|
|
27
|
+
/**
|
|
28
|
+
* Session Attach P2 — wait mode:
|
|
29
|
+
*
|
|
30
|
+
* - POST /v1/environments/bridge persists session_mode:'attach'.
|
|
31
|
+
* - GET /v1/environments/:id/assignment returns the first open non-ACP
|
|
32
|
+
* session on the env (assigned:false until the Web UI binds one).
|
|
33
|
+
* - GET /web/environments surfaces attach_waiting for waiting workers.
|
|
34
|
+
*/
|
|
35
|
+
|
|
36
|
+
function freshDb(): Database {
|
|
37
|
+
try {
|
|
38
|
+
resetDbSingleton()
|
|
39
|
+
} catch {}
|
|
40
|
+
const path = resolve(
|
|
41
|
+
tmpdir(),
|
|
42
|
+
`rcs-attach-wait-${randomUUID().replace(/-/g, '').slice(0, 8)}.db`,
|
|
43
|
+
)
|
|
44
|
+
return initDatabase(path)
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
function createUser(db: Database): { id: string; username: string } {
|
|
48
|
+
const username = `user_${randomUUID().slice(0, 6)}`
|
|
49
|
+
const user = createUserDirectly(db, { username, role: 'member' })
|
|
50
|
+
return { id: user.id, username: user.username }
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
function rctAuth(userId: string): string {
|
|
54
|
+
return `Bearer ${issueSessionToken(userId, getDb()).accessToken}`
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
const ADMIN_KEY = { Authorization: 'Bearer test-api-key' }
|
|
58
|
+
const JSON_HDRS = { 'Content-Type': 'application/json' }
|
|
59
|
+
|
|
60
|
+
function createApp() {
|
|
61
|
+
const app = new Hono()
|
|
62
|
+
app.route('/v1/environments', v1Environments)
|
|
63
|
+
app.route('/web', webEnvironments)
|
|
64
|
+
return app
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
describe('Session Attach wait mode', () => {
|
|
68
|
+
let app: Hono
|
|
69
|
+
let db: Database
|
|
70
|
+
let owner: { id: string; username: string }
|
|
71
|
+
|
|
72
|
+
beforeEach(() => {
|
|
73
|
+
db = freshDb()
|
|
74
|
+
storeReset()
|
|
75
|
+
app = createApp()
|
|
76
|
+
owner = createUser(db)
|
|
77
|
+
})
|
|
78
|
+
|
|
79
|
+
test('POST /bridge with session_mode=attach persists the mode', async () => {
|
|
80
|
+
const res = await app.request('/v1/environments/bridge', {
|
|
81
|
+
method: 'POST',
|
|
82
|
+
headers: { ...JSON_HDRS, ...ADMIN_KEY, 'X-User-Id': owner.username },
|
|
83
|
+
body: JSON.stringify({ machine_name: 'mac1', session_mode: 'attach' }),
|
|
84
|
+
})
|
|
85
|
+
expect(res.status).toBe(200)
|
|
86
|
+
const envId = ((await res.json()) as { environment_id: string })
|
|
87
|
+
.environment_id
|
|
88
|
+
expect(storeGetEnvironment(envId)?.sessionMode).toBe('attach')
|
|
89
|
+
})
|
|
90
|
+
|
|
91
|
+
test('POST /bridge without session_mode stays create-mode', async () => {
|
|
92
|
+
const res = await app.request('/v1/environments/bridge', {
|
|
93
|
+
method: 'POST',
|
|
94
|
+
headers: { ...JSON_HDRS, ...ADMIN_KEY, 'X-User-Id': owner.username },
|
|
95
|
+
body: JSON.stringify({ machine_name: 'mac1' }),
|
|
96
|
+
})
|
|
97
|
+
expect(res.status).toBe(200)
|
|
98
|
+
const envId = ((await res.json()) as { environment_id: string })
|
|
99
|
+
.environment_id
|
|
100
|
+
expect(storeGetEnvironment(envId)?.sessionMode ?? null).toBeNull()
|
|
101
|
+
})
|
|
102
|
+
|
|
103
|
+
test('assignment: unassigned env → assigned:false', async () => {
|
|
104
|
+
const env = storeCreateEnvironment({
|
|
105
|
+
secret: 'test-api-key',
|
|
106
|
+
machineName: 'mac1',
|
|
107
|
+
ownerUserId: owner.id,
|
|
108
|
+
sessionMode: 'attach',
|
|
109
|
+
})
|
|
110
|
+
// Age the heartbeat past the disconnect timeout, then verify the poll
|
|
111
|
+
// refreshes it (P0-2: without this the disconnect monitor kills the
|
|
112
|
+
// waiting env after 5 minutes and the CLI dead-waits its deadline).
|
|
113
|
+
const stale = new Date(Date.now() - 10 * 60 * 1000)
|
|
114
|
+
storeUpdateEnvironment(env.id, { lastPollAt: stale })
|
|
115
|
+
const before = storeGetEnvironment(env.id)?.lastPollAt?.getTime()
|
|
116
|
+
|
|
117
|
+
const res = await app.request(`/v1/environments/${env.id}/assignment`, {
|
|
118
|
+
headers: { ...ADMIN_KEY },
|
|
119
|
+
})
|
|
120
|
+
expect(res.status).toBe(200)
|
|
121
|
+
expect(await res.json()).toEqual({ assigned: false })
|
|
122
|
+
const after = storeGetEnvironment(env.id)?.lastPollAt?.getTime()
|
|
123
|
+
expect(after).not.toBe(before)
|
|
124
|
+
expect(after ?? 0).toBeGreaterThan(stale.getTime())
|
|
125
|
+
})
|
|
126
|
+
|
|
127
|
+
test('assignment: session bound to the env (web attach) → assigned with session id', async () => {
|
|
128
|
+
const env = storeCreateEnvironment({
|
|
129
|
+
secret: 'test-api-key',
|
|
130
|
+
machineName: 'mac1',
|
|
131
|
+
ownerUserId: owner.id,
|
|
132
|
+
sessionMode: 'attach',
|
|
133
|
+
})
|
|
134
|
+
const session = createSession({
|
|
135
|
+
environment_id: env.id,
|
|
136
|
+
title: 'Team session',
|
|
137
|
+
source: 'web',
|
|
138
|
+
})
|
|
139
|
+
storeBindSession(session.id, owner.id, 'user')
|
|
140
|
+
|
|
141
|
+
const res = await app.request(`/v1/environments/${env.id}/assignment`, {
|
|
142
|
+
headers: { ...ADMIN_KEY },
|
|
143
|
+
})
|
|
144
|
+
expect(res.status).toBe(200)
|
|
145
|
+
const body = (await res.json()) as {
|
|
146
|
+
assigned: boolean
|
|
147
|
+
session_id?: string
|
|
148
|
+
}
|
|
149
|
+
expect(body.assigned).toBe(true)
|
|
150
|
+
expect(body.session_id).toBe(session.id)
|
|
151
|
+
})
|
|
152
|
+
|
|
153
|
+
test('assignment: archived sessions do not satisfy the assignment', async () => {
|
|
154
|
+
const env = storeCreateEnvironment({
|
|
155
|
+
secret: 'test-api-key',
|
|
156
|
+
machineName: 'mac1',
|
|
157
|
+
ownerUserId: owner.id,
|
|
158
|
+
sessionMode: 'attach',
|
|
159
|
+
})
|
|
160
|
+
const session = createSession({
|
|
161
|
+
environment_id: env.id,
|
|
162
|
+
title: 'Archived session',
|
|
163
|
+
source: 'web',
|
|
164
|
+
})
|
|
165
|
+
archiveSession(session.id)
|
|
166
|
+
|
|
167
|
+
const res = await app.request(`/v1/environments/${env.id}/assignment`, {
|
|
168
|
+
headers: { ...ADMIN_KEY },
|
|
169
|
+
})
|
|
170
|
+
expect(res.status).toBe(200)
|
|
171
|
+
expect(await res.json()).toEqual({ assigned: false })
|
|
172
|
+
})
|
|
173
|
+
|
|
174
|
+
test('assignment: unknown env → 404', async () => {
|
|
175
|
+
const res = await app.request('/v1/environments/env_missing/assignment', {
|
|
176
|
+
headers: { ...ADMIN_KEY },
|
|
177
|
+
})
|
|
178
|
+
expect(res.status).toBe(404)
|
|
179
|
+
})
|
|
180
|
+
|
|
181
|
+
test('web environments exposes attach_waiting for waiting workers', async () => {
|
|
182
|
+
storeCreateEnvironment({
|
|
183
|
+
secret: 'test-api-key',
|
|
184
|
+
machineName: 'waiting-cli',
|
|
185
|
+
ownerUserId: owner.id,
|
|
186
|
+
sessionMode: 'attach',
|
|
187
|
+
})
|
|
188
|
+
// A create-mode env with a bound session — never attach_waiting.
|
|
189
|
+
const busyEnv = storeCreateEnvironment({
|
|
190
|
+
secret: 'test-api-key',
|
|
191
|
+
machineName: 'busy-cli',
|
|
192
|
+
ownerUserId: owner.id,
|
|
193
|
+
})
|
|
194
|
+
createSession({
|
|
195
|
+
environment_id: busyEnv.id,
|
|
196
|
+
title: 's',
|
|
197
|
+
source: 'web',
|
|
198
|
+
})
|
|
199
|
+
|
|
200
|
+
const res = await app.request('/web/environments', {
|
|
201
|
+
headers: { Authorization: rctAuth(owner.id) },
|
|
202
|
+
})
|
|
203
|
+
expect(res.status).toBe(200)
|
|
204
|
+
const envs = (await res.json()) as Array<{
|
|
205
|
+
machine_name: string
|
|
206
|
+
attach_waiting?: boolean
|
|
207
|
+
}>
|
|
208
|
+
const waiting = envs.find(e => e.machine_name === 'waiting-cli')
|
|
209
|
+
const busy = envs.find(e => e.machine_name === 'busy-cli')
|
|
210
|
+
expect(waiting?.attach_waiting).toBe(true)
|
|
211
|
+
expect(busy?.attach_waiting ?? false).toBe(false)
|
|
212
|
+
})
|
|
213
|
+
})
|