@juspay/shooter 1.18.0 → 1.20.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (367) hide show
  1. package/build/client/_app/immutable/assets/{0.NV8k8wxG.css → 0.BwNtE8TX.css} +1 -1
  2. package/build/client/_app/immutable/assets/0.BwNtE8TX.css.br +0 -0
  3. package/build/client/_app/immutable/assets/{0.NV8k8wxG.css.gz → 0.BwNtE8TX.css.gz} +0 -0
  4. package/build/client/_app/immutable/assets/11.F10lvwyh.css +1 -0
  5. package/build/client/_app/immutable/assets/11.F10lvwyh.css.br +0 -0
  6. package/build/client/_app/immutable/assets/11.F10lvwyh.css.gz +0 -0
  7. package/build/client/_app/immutable/assets/8.BYgAX7hR.css +1 -0
  8. package/build/client/_app/immutable/assets/8.BYgAX7hR.css.br +0 -0
  9. package/build/client/_app/immutable/assets/8.BYgAX7hR.css.gz +0 -0
  10. package/build/client/_app/immutable/assets/9.DV6pZunn.css +1 -0
  11. package/build/client/_app/immutable/assets/9.DV6pZunn.css.br +0 -0
  12. package/build/client/_app/immutable/assets/9.DV6pZunn.css.gz +0 -0
  13. package/build/client/_app/immutable/chunks/{DZQMsHM5.js → 2rBV5OkJ.js} +1 -1
  14. package/build/client/_app/immutable/chunks/2rBV5OkJ.js.br +0 -0
  15. package/build/client/_app/immutable/chunks/2rBV5OkJ.js.gz +0 -0
  16. package/build/client/_app/immutable/chunks/{B9WQy_3X.js → BB2l8o4X.js} +1 -1
  17. package/build/client/_app/immutable/chunks/BB2l8o4X.js.br +0 -0
  18. package/build/client/_app/immutable/chunks/BB2l8o4X.js.gz +0 -0
  19. package/build/client/_app/immutable/chunks/{Cg3dlX05.js → BPDiEZo0.js} +2 -2
  20. package/build/client/_app/immutable/chunks/BPDiEZo0.js.br +0 -0
  21. package/build/client/_app/immutable/chunks/BPDiEZo0.js.gz +0 -0
  22. package/build/client/_app/immutable/chunks/{C_9BZILB.js → BcpydfqI.js} +1 -1
  23. package/build/client/_app/immutable/chunks/BcpydfqI.js.br +0 -0
  24. package/build/client/_app/immutable/chunks/BcpydfqI.js.gz +0 -0
  25. package/build/client/_app/immutable/chunks/{BRqaaL5D.js → BvmdJful.js} +1 -1
  26. package/build/client/_app/immutable/chunks/BvmdJful.js.br +0 -0
  27. package/build/client/_app/immutable/chunks/BvmdJful.js.gz +0 -0
  28. package/build/client/_app/immutable/chunks/C_YNQL8b.js +3 -0
  29. package/build/client/_app/immutable/chunks/C_YNQL8b.js.br +0 -0
  30. package/build/client/_app/immutable/chunks/C_YNQL8b.js.gz +0 -0
  31. package/build/client/_app/immutable/chunks/{C5VOyQCG.js → ClIPTXf3.js} +1 -1
  32. package/build/client/_app/immutable/chunks/ClIPTXf3.js.br +0 -0
  33. package/build/client/_app/immutable/chunks/ClIPTXf3.js.gz +0 -0
  34. package/build/client/_app/immutable/chunks/{8lO1IL7u.js → DIZ3Qst5.js} +1 -1
  35. package/build/client/_app/immutable/chunks/DIZ3Qst5.js.br +0 -0
  36. package/build/client/_app/immutable/chunks/{8lO1IL7u.js.gz → DIZ3Qst5.js.gz} +0 -0
  37. package/build/client/_app/immutable/chunks/{DJvX78LW.js → DT4H19pV.js} +1 -1
  38. package/build/client/_app/immutable/chunks/DT4H19pV.js.br +0 -0
  39. package/build/client/_app/immutable/chunks/DT4H19pV.js.gz +0 -0
  40. package/build/client/_app/immutable/chunks/{DYuMZGL5.js → DWmC0QM7.js} +1 -1
  41. package/build/client/_app/immutable/chunks/DWmC0QM7.js.br +0 -0
  42. package/build/client/_app/immutable/chunks/DWmC0QM7.js.gz +0 -0
  43. package/build/client/_app/immutable/chunks/J5-Cr5oR.js +6 -0
  44. package/build/client/_app/immutable/chunks/J5-Cr5oR.js.br +0 -0
  45. package/build/client/_app/immutable/chunks/J5-Cr5oR.js.gz +0 -0
  46. package/build/client/_app/immutable/chunks/{DZvnhU_8.js → ZS5XYDx_.js} +2 -2
  47. package/build/client/_app/immutable/chunks/ZS5XYDx_.js.br +0 -0
  48. package/build/client/_app/immutable/chunks/ZS5XYDx_.js.gz +0 -0
  49. package/build/client/_app/immutable/entry/app.Bd-DfeJi.js +2 -0
  50. package/build/client/_app/immutable/entry/app.Bd-DfeJi.js.br +0 -0
  51. package/build/client/_app/immutable/entry/app.Bd-DfeJi.js.gz +0 -0
  52. package/build/client/_app/immutable/entry/start.evvp4tX7.js +1 -0
  53. package/build/client/_app/immutable/entry/start.evvp4tX7.js.br +2 -0
  54. package/build/client/_app/immutable/entry/start.evvp4tX7.js.gz +0 -0
  55. package/build/client/_app/immutable/nodes/0.Bl-1LQWM.js +10 -0
  56. package/build/client/_app/immutable/nodes/0.Bl-1LQWM.js.br +0 -0
  57. package/build/client/_app/immutable/nodes/0.Bl-1LQWM.js.gz +0 -0
  58. package/build/client/_app/immutable/nodes/{1.C4eFlqSB.js → 1.DT4dq6Ay.js} +1 -1
  59. package/build/client/_app/immutable/nodes/1.DT4dq6Ay.js.br +0 -0
  60. package/build/client/_app/immutable/nodes/1.DT4dq6Ay.js.gz +0 -0
  61. package/build/client/_app/immutable/nodes/{8.Bs362gyb.js → 10.CF7RGXpe.js} +2 -2
  62. package/build/client/_app/immutable/nodes/10.CF7RGXpe.js.br +0 -0
  63. package/build/client/_app/immutable/nodes/10.CF7RGXpe.js.gz +0 -0
  64. package/build/client/_app/immutable/nodes/11.BV_G7yLI.js +2 -0
  65. package/build/client/_app/immutable/nodes/11.BV_G7yLI.js.br +0 -0
  66. package/build/client/_app/immutable/nodes/11.BV_G7yLI.js.gz +0 -0
  67. package/build/client/_app/immutable/nodes/{2.CdC092Za.js → 2.DcRhsjYp.js} +2 -2
  68. package/build/client/_app/immutable/nodes/2.DcRhsjYp.js.br +0 -0
  69. package/build/client/_app/immutable/nodes/2.DcRhsjYp.js.gz +0 -0
  70. package/build/client/_app/immutable/nodes/{3.Dhf4ZWW0.js → 3.0MMe3oxR.js} +3 -3
  71. package/build/client/_app/immutable/nodes/3.0MMe3oxR.js.br +0 -0
  72. package/build/client/_app/immutable/nodes/3.0MMe3oxR.js.gz +0 -0
  73. package/build/client/_app/immutable/nodes/{4.BSVqdrrD.js → 4.CBX9A3ka.js} +2 -2
  74. package/build/client/_app/immutable/nodes/4.CBX9A3ka.js.br +0 -0
  75. package/build/client/_app/immutable/nodes/4.CBX9A3ka.js.gz +0 -0
  76. package/build/client/_app/immutable/nodes/{5.Cfj35gpY.js → 5.DIVKuZc9.js} +1 -1
  77. package/build/client/_app/immutable/nodes/5.DIVKuZc9.js.br +0 -0
  78. package/build/client/_app/immutable/nodes/5.DIVKuZc9.js.gz +0 -0
  79. package/build/client/_app/immutable/nodes/{6.B3SEB_li.js → 6.ComiWlV6.js} +1 -1
  80. package/build/client/_app/immutable/nodes/6.ComiWlV6.js.br +0 -0
  81. package/build/client/_app/immutable/nodes/6.ComiWlV6.js.gz +0 -0
  82. package/build/client/_app/immutable/nodes/{7.DV8cJ1lX.js → 7.vkPx1kVP.js} +1 -1
  83. package/build/client/_app/immutable/nodes/7.vkPx1kVP.js.br +0 -0
  84. package/build/client/_app/immutable/nodes/7.vkPx1kVP.js.gz +0 -0
  85. package/build/client/_app/immutable/nodes/8.Bmr3sWbS.js +1 -0
  86. package/build/client/_app/immutable/nodes/8.Bmr3sWbS.js.br +0 -0
  87. package/build/client/_app/immutable/nodes/8.Bmr3sWbS.js.gz +0 -0
  88. package/build/client/_app/immutable/nodes/9.CAJucyeI.js +2 -0
  89. package/build/client/_app/immutable/nodes/9.CAJucyeI.js.br +0 -0
  90. package/build/client/_app/immutable/nodes/9.CAJucyeI.js.gz +0 -0
  91. package/build/client/_app/version.json +1 -1
  92. package/build/client/_app/version.json.br +0 -0
  93. package/build/client/_app/version.json.gz +0 -0
  94. package/build/server/chunks/{0-Cd7jY0a7.js → 0-DDGB6CRT.js} +4 -4
  95. package/build/server/chunks/{0-Cd7jY0a7.js.map → 0-DDGB6CRT.js.map} +1 -1
  96. package/build/server/chunks/1-DEjonQXD.js +9 -0
  97. package/build/server/chunks/{1-C4BOGoJY.js.map → 1-DEjonQXD.js.map} +1 -1
  98. package/build/server/chunks/10-BK1kiiiw.js +9 -0
  99. package/build/server/chunks/10-BK1kiiiw.js.map +1 -0
  100. package/build/server/chunks/11-CJPjkEF3.js +9 -0
  101. package/build/server/chunks/11-CJPjkEF3.js.map +1 -0
  102. package/build/server/chunks/{2-Ba0mNwJ6.js → 2-RLnhlWh5.js} +3 -3
  103. package/build/server/chunks/{2-Ba0mNwJ6.js.map → 2-RLnhlWh5.js.map} +1 -1
  104. package/build/server/chunks/{3-Pg8t1uJU.js → 3-Dd4pJBqZ.js} +3 -3
  105. package/build/server/chunks/{3-Pg8t1uJU.js.map → 3-Dd4pJBqZ.js.map} +1 -1
  106. package/build/server/chunks/{4-BtYdKCVW.js → 4-Bb5VFhsO.js} +3 -3
  107. package/build/server/chunks/{4-BtYdKCVW.js.map → 4-Bb5VFhsO.js.map} +1 -1
  108. package/build/server/chunks/{5-CvJK3PiH.js → 5-oNoWuIsn.js} +3 -3
  109. package/build/server/chunks/{5-CvJK3PiH.js.map → 5-oNoWuIsn.js.map} +1 -1
  110. package/build/server/chunks/6-DdRMnKNa.js +9 -0
  111. package/build/server/chunks/{6-D8xbnTSo.js.map → 6-DdRMnKNa.js.map} +1 -1
  112. package/build/server/chunks/7-vLOMMetm.js +9 -0
  113. package/build/server/chunks/{7-CkVK06S0.js.map → 7-vLOMMetm.js.map} +1 -1
  114. package/build/server/chunks/8-rJyiQLFs.js +9 -0
  115. package/build/server/chunks/8-rJyiQLFs.js.map +1 -0
  116. package/build/server/chunks/9-CVSNNYED.js +9 -0
  117. package/build/server/chunks/9-CVSNNYED.js.map +1 -0
  118. package/build/server/chunks/Banner-BgaAs1rs.js +90 -0
  119. package/build/server/chunks/Banner-BgaAs1rs.js.map +1 -0
  120. package/build/server/chunks/{Button-B5dU-ntz.js → Button-D0hZ7JYt.js} +2 -2
  121. package/build/server/chunks/Button-D0hZ7JYt.js.map +1 -0
  122. package/build/server/chunks/{Icon-C7Ml3GX6.js → Icon-D0GBnDcs.js} +3 -3
  123. package/build/server/chunks/Icon-D0GBnDcs.js.map +1 -0
  124. package/build/server/chunks/{Input-CPGO0sbS.js → Input-OmIiydSx.js} +2 -2
  125. package/build/server/chunks/Input-OmIiydSx.js.map +1 -0
  126. package/build/server/chunks/{Pill-CcrtCejm.js → Pill-4xJ-VhAA.js} +3 -3
  127. package/build/server/chunks/Pill-4xJ-VhAA.js.map +1 -0
  128. package/build/server/chunks/{Shimmer-C5jkvGr1.js → Shimmer-Dw2uvTC1.js} +2 -2
  129. package/build/server/chunks/Shimmer-Dw2uvTC1.js.map +1 -0
  130. package/build/server/chunks/{_error.svelte-CSIxs-ab.js → _error.svelte-CZnkxeLr.js} +8 -8
  131. package/build/server/chunks/_error.svelte-CZnkxeLr.js.map +1 -0
  132. package/build/server/chunks/{_layout.svelte-noB4j-v2.js → _layout.svelte-DfgNGGiM.js} +16 -11
  133. package/build/server/chunks/_layout.svelte-DfgNGGiM.js.map +1 -0
  134. package/build/server/chunks/{_page.svelte-DnTpPnPR.js → _page.svelte-BLo2v_8E.js} +7 -88
  135. package/build/server/chunks/_page.svelte-BLo2v_8E.js.map +1 -0
  136. package/build/server/chunks/_page.svelte-BTlfUsBp.js +43 -0
  137. package/build/server/chunks/_page.svelte-BTlfUsBp.js.map +1 -0
  138. package/build/server/chunks/{_page.svelte-BV0XyYJZ.js → _page.svelte-BX2FMgSg.js} +4 -4
  139. package/build/server/chunks/_page.svelte-BX2FMgSg.js.map +1 -0
  140. package/build/server/chunks/{_page.svelte-BUkm2304.js → _page.svelte-C7B0qdrC.js} +5 -5
  141. package/build/server/chunks/_page.svelte-C7B0qdrC.js.map +1 -0
  142. package/build/server/chunks/{_page.svelte-Dmg-RFCg.js → _page.svelte-CE7COWnF.js} +7 -7
  143. package/build/server/chunks/_page.svelte-CE7COWnF.js.map +1 -0
  144. package/build/server/chunks/{_page.svelte-BfB8maoc.js → _page.svelte-CWsjjd4l.js} +9 -9
  145. package/build/server/chunks/_page.svelte-CWsjjd4l.js.map +1 -0
  146. package/build/server/chunks/_page.svelte-D5S2hkBk.js +104 -0
  147. package/build/server/chunks/_page.svelte-D5S2hkBk.js.map +1 -0
  148. package/build/server/chunks/{_page.svelte-B6qyh-K-.js → _page.svelte-D_Ey8QRG.js} +11 -11
  149. package/build/server/chunks/_page.svelte-D_Ey8QRG.js.map +1 -0
  150. package/build/server/chunks/{_page.svelte-C60lAagP.js → _page.svelte-dabsQl9c.js} +210 -9
  151. package/build/server/chunks/_page.svelte-dabsQl9c.js.map +1 -0
  152. package/build/server/chunks/{_page.svelte-DuzZr5dA.js → _page.svelte-tBuIq8Pg.js} +11 -11
  153. package/build/server/chunks/_page.svelte-tBuIq8Pg.js.map +1 -0
  154. package/build/server/chunks/{_server.ts-CyjDrcZN.js → _server.ts-AnBXfZXh.js} +10 -2
  155. package/build/server/chunks/_server.ts-AnBXfZXh.js.map +1 -0
  156. package/build/server/chunks/_server.ts-B-evHL2q.js +13 -0
  157. package/build/server/chunks/_server.ts-B-evHL2q.js.map +1 -0
  158. package/build/server/chunks/_server.ts-B2wIgsW4.js +95 -0
  159. package/build/server/chunks/_server.ts-B2wIgsW4.js.map +1 -0
  160. package/build/server/chunks/_server.ts-BaaY7Z9D.js +77 -0
  161. package/build/server/chunks/_server.ts-BaaY7Z9D.js.map +1 -0
  162. package/build/server/chunks/_server.ts-C0317RBD.js +57 -0
  163. package/build/server/chunks/_server.ts-C0317RBD.js.map +1 -0
  164. package/build/server/chunks/{_server.ts-Bu3s5hfv.js → _server.ts-CJGyN8mw.js} +18 -10
  165. package/build/server/chunks/_server.ts-CJGyN8mw.js.map +1 -0
  166. package/build/server/chunks/_server.ts-CVPZOpiv.js +23 -0
  167. package/build/server/chunks/_server.ts-CVPZOpiv.js.map +1 -0
  168. package/build/server/chunks/{_server.ts-DZgfQKiH.js → _server.ts-D9ir7u24.js} +2 -2
  169. package/build/server/chunks/{_server.ts-DZgfQKiH.js.map → _server.ts-D9ir7u24.js.map} +1 -1
  170. package/build/server/chunks/{_server.ts-DZP2lhaY.js → _server.ts-DEx9-epI.js} +20 -8
  171. package/build/server/chunks/_server.ts-DEx9-epI.js.map +1 -0
  172. package/build/server/chunks/{_server.ts-BA_uWcPw.js → _server.ts-DKNIsQeH.js} +6 -4
  173. package/build/server/chunks/_server.ts-DKNIsQeH.js.map +1 -0
  174. package/build/server/chunks/_server.ts-DkZX_O9a.js +39 -0
  175. package/build/server/chunks/_server.ts-DkZX_O9a.js.map +1 -0
  176. package/build/server/chunks/_server.ts-DpRr0Tfh.js +68 -0
  177. package/build/server/chunks/_server.ts-DpRr0Tfh.js.map +1 -0
  178. package/build/server/chunks/{_server.ts-CwAjt91u.js → _server.ts-Dz9Jd9Jh.js} +6 -4
  179. package/build/server/chunks/{_server.ts-CwAjt91u.js.map → _server.ts-Dz9Jd9Jh.js.map} +1 -1
  180. package/build/server/chunks/_server.ts-Mttr0-Sl.js +48 -0
  181. package/build/server/chunks/_server.ts-Mttr0-Sl.js.map +1 -0
  182. package/build/server/chunks/{_server.ts-Bjbr7glm.js → _server.ts-QN-Bo5ql.js} +12 -5
  183. package/build/server/chunks/_server.ts-QN-Bo5ql.js.map +1 -0
  184. package/build/server/chunks/{_server.ts-BrqaMMAa.js → _server.ts-W6i3EnGX.js} +29 -6
  185. package/build/server/chunks/_server.ts-W6i3EnGX.js.map +1 -0
  186. package/build/server/chunks/{_server.ts-DZ5naqSL.js → _server.ts-bk_EeAdY.js} +6 -2
  187. package/build/server/chunks/_server.ts-bk_EeAdY.js.map +1 -0
  188. package/build/server/chunks/_server.ts-jtqWDWcf.js +45 -0
  189. package/build/server/chunks/_server.ts-jtqWDWcf.js.map +1 -0
  190. package/build/server/chunks/{cache-Me3zUAaD.js → cache-BlMaDsHi.js} +2 -2
  191. package/build/server/chunks/cache-BlMaDsHi.js.map +1 -0
  192. package/build/server/chunks/{client-CfNnl32g.js → client-Ds1brw-8.js} +4 -4
  193. package/build/server/chunks/{client-CfNnl32g.js.map → client-Ds1brw-8.js.map} +1 -1
  194. package/build/server/chunks/client2-DngLdcUc.js +7 -0
  195. package/build/server/chunks/{client2-DDP30_vY.js.map → client2-DngLdcUc.js.map} +1 -1
  196. package/build/server/chunks/coordinator-DMU_ADXf.js +530 -0
  197. package/build/server/chunks/coordinator-DMU_ADXf.js.map +1 -0
  198. package/build/server/chunks/guest-registry-t0-7Zv5q.js +39 -0
  199. package/build/server/chunks/guest-registry-t0-7Zv5q.js.map +1 -0
  200. package/build/server/chunks/{index-CJrGuxuM.js → index-CoYB03g7.js} +2 -2
  201. package/build/server/chunks/{index-CJrGuxuM.js.map → index-CoYB03g7.js.map} +1 -1
  202. package/build/server/chunks/{index-server--49oHtA0.js → index-server-Bq3cnK69.js} +2 -2
  203. package/build/server/chunks/{index-server--49oHtA0.js.map → index-server-Bq3cnK69.js.map} +1 -1
  204. package/build/server/chunks/{index2-MY7PXeAc.js → index2-dSGQ9Eaa.js} +2 -2
  205. package/build/server/chunks/{index2-MY7PXeAc.js.map → index2-dSGQ9Eaa.js.map} +1 -1
  206. package/build/server/chunks/{pty-manager-DmNSCKAr.js → pty-manager-CkZNoW1t.js} +7 -2
  207. package/build/server/chunks/pty-manager-CkZNoW1t.js.map +1 -0
  208. package/build/server/chunks/qwen-reader-DGfUbKaJ.js.map +1 -1
  209. package/build/server/chunks/{registry-Kcw2UCMv.js → registry-D4J_CuzW.js} +2 -2
  210. package/build/server/chunks/registry-D4J_CuzW.js.map +1 -0
  211. package/build/server/chunks/{root-xvQIR1Bt.js → root-D4IoFC8F.js} +2 -2
  212. package/build/server/chunks/root-D4IoFC8F.js.map +1 -0
  213. package/build/server/chunks/share-auth-BS7JuiHf.js +27 -0
  214. package/build/server/chunks/share-auth-BS7JuiHf.js.map +1 -0
  215. package/build/server/chunks/share-store-B9jMpVg0.js +127 -0
  216. package/build/server/chunks/share-store-B9jMpVg0.js.map +1 -0
  217. package/build/server/chunks/{state.svelte-RCtlkrNH.js → state.svelte-CmHqngc_.js} +3 -3
  218. package/build/server/chunks/{state.svelte-RCtlkrNH.js.map → state.svelte-CmHqngc_.js.map} +1 -1
  219. package/build/server/chunks/{stores-C-LqoonT.js → stores-CRYxfF0o.js} +4 -4
  220. package/build/server/chunks/stores-CRYxfF0o.js.map +1 -0
  221. package/build/server/chunks/super-session-handler-DPyxFgmz.js +22 -0
  222. package/build/server/chunks/super-session-handler-DPyxFgmz.js.map +1 -0
  223. package/build/server/index.js +4 -4
  224. package/build/server/index.js.map +1 -1
  225. package/build/server/manifest.js +101 -22
  226. package/build/server/manifest.js.map +1 -1
  227. package/package.json +2 -2
  228. package/scripts/e2e-all-features.sh +41 -2
  229. package/server.ts +33 -3
  230. package/src/lib/modules/client/terminal/ShareGate.svelte +96 -0
  231. package/src/lib/modules/client/terminal/ShareSheet.svelte +395 -0
  232. package/src/lib/modules/client/terminal/xterm-wrapper.ts +19 -2
  233. package/src/lib/modules/server/sos/coordinator.ts +492 -0
  234. package/src/lib/modules/server/sos/policy-gate.ts +56 -0
  235. package/src/lib/modules/server/sos/relay-store.ts +159 -0
  236. package/src/lib/modules/server/terminal/pty-input.ts +37 -0
  237. package/src/lib/modules/server/terminal/pty-manager.ts +6 -0
  238. package/src/lib/modules/server/terminal/share-auth.ts +37 -0
  239. package/src/lib/modules/server/terminal/share-store.ts +172 -0
  240. package/src/lib/modules/server/ws/guest-registry.ts +49 -0
  241. package/src/lib/modules/server/ws/server.ts +28 -4
  242. package/src/lib/modules/server/ws/session-handler.ts +24 -5
  243. package/src/lib/modules/server/ws/super-session-handler.ts +200 -0
  244. package/src/lib/modules/server/ws/terminal-handler.ts +21 -2
  245. package/src/lib/modules/server/ws/ticket-store.ts +18 -10
  246. package/src/lib/types/generated/Client.ts +25 -1
  247. package/src/lib/types/generated/Share.ts +404 -0
  248. package/src/lib/types/generated/WsProtocol.ts +73 -2
  249. package/src/lib/types/generated/index.ts +1 -0
  250. package/src/lib/types/index.ts +2 -1
  251. package/src/lib/types/sos.ts +134 -0
  252. package/src/lib/types/terminal-client.ts +19 -2
  253. package/src/lib/types/ws.ts +1 -0
  254. package/src/routes/+layout.svelte +9 -2
  255. package/src/routes/api/sos/+server.ts +36 -0
  256. package/src/routes/api/sos/[id]/+server.ts +55 -0
  257. package/src/routes/api/sos/[id]/inject/+server.ts +44 -0
  258. package/src/routes/api/sos/[id]/members/+server.ts +47 -0
  259. package/src/routes/api/sos/[id]/members/[mid]/+server.ts +17 -0
  260. package/src/routes/api/sos/[id]/rules/+server.ts +85 -0
  261. package/src/routes/api/terminals/[id]/+server.ts +14 -3
  262. package/src/routes/api/terminals/[id]/paste-image/+server.ts +8 -4
  263. package/src/routes/api/terminals/[id]/resize/+server.ts +8 -4
  264. package/src/routes/api/terminals/[id]/share/+server.ts +98 -0
  265. package/src/routes/api/terminals/[id]/share/auth/+server.ts +81 -0
  266. package/src/routes/api/terminals/[id]/share/status/+server.ts +11 -0
  267. package/src/routes/api/ws-ticket/+server.ts +26 -5
  268. package/src/routes/sos/+page.svelte +195 -0
  269. package/src/routes/sos/[id]/+page.svelte +677 -0
  270. package/src/routes/terminals/[id]/+page.svelte +184 -43
  271. package/build/client/_app/immutable/assets/0.NV8k8wxG.css.br +0 -0
  272. package/build/client/_app/immutable/assets/9.v5KA95xm.css +0 -1
  273. package/build/client/_app/immutable/assets/9.v5KA95xm.css.br +0 -0
  274. package/build/client/_app/immutable/assets/9.v5KA95xm.css.gz +0 -0
  275. package/build/client/_app/immutable/chunks/8lO1IL7u.js.br +0 -0
  276. package/build/client/_app/immutable/chunks/B9WQy_3X.js.br +0 -0
  277. package/build/client/_app/immutable/chunks/B9WQy_3X.js.gz +0 -0
  278. package/build/client/_app/immutable/chunks/BRqaaL5D.js.br +0 -0
  279. package/build/client/_app/immutable/chunks/BRqaaL5D.js.gz +0 -0
  280. package/build/client/_app/immutable/chunks/C5VOyQCG.js.br +0 -0
  281. package/build/client/_app/immutable/chunks/C5VOyQCG.js.gz +0 -0
  282. package/build/client/_app/immutable/chunks/CR6bkGJW.js +0 -6
  283. package/build/client/_app/immutable/chunks/CR6bkGJW.js.br +0 -0
  284. package/build/client/_app/immutable/chunks/CR6bkGJW.js.gz +0 -0
  285. package/build/client/_app/immutable/chunks/C_9BZILB.js.br +0 -0
  286. package/build/client/_app/immutable/chunks/C_9BZILB.js.gz +0 -0
  287. package/build/client/_app/immutable/chunks/Cg3dlX05.js.br +0 -0
  288. package/build/client/_app/immutable/chunks/Cg3dlX05.js.gz +0 -0
  289. package/build/client/_app/immutable/chunks/DJvX78LW.js.br +0 -0
  290. package/build/client/_app/immutable/chunks/DJvX78LW.js.gz +0 -0
  291. package/build/client/_app/immutable/chunks/DYuMZGL5.js.br +0 -0
  292. package/build/client/_app/immutable/chunks/DYuMZGL5.js.gz +0 -0
  293. package/build/client/_app/immutable/chunks/DZQMsHM5.js.br +0 -0
  294. package/build/client/_app/immutable/chunks/DZQMsHM5.js.gz +0 -0
  295. package/build/client/_app/immutable/chunks/DZvnhU_8.js.br +0 -0
  296. package/build/client/_app/immutable/chunks/DZvnhU_8.js.gz +0 -0
  297. package/build/client/_app/immutable/chunks/nWG9RHyB.js +0 -3
  298. package/build/client/_app/immutable/chunks/nWG9RHyB.js.br +0 -0
  299. package/build/client/_app/immutable/chunks/nWG9RHyB.js.gz +0 -0
  300. package/build/client/_app/immutable/entry/app.f46Ko1hu.js +0 -2
  301. package/build/client/_app/immutable/entry/app.f46Ko1hu.js.br +0 -0
  302. package/build/client/_app/immutable/entry/app.f46Ko1hu.js.gz +0 -0
  303. package/build/client/_app/immutable/entry/start.BVDjNnXt.js +0 -1
  304. package/build/client/_app/immutable/entry/start.BVDjNnXt.js.br +0 -2
  305. package/build/client/_app/immutable/entry/start.BVDjNnXt.js.gz +0 -0
  306. package/build/client/_app/immutable/nodes/0.D_9EwVmq.js +0 -7
  307. package/build/client/_app/immutable/nodes/0.D_9EwVmq.js.br +0 -0
  308. package/build/client/_app/immutable/nodes/0.D_9EwVmq.js.gz +0 -0
  309. package/build/client/_app/immutable/nodes/1.C4eFlqSB.js.br +0 -0
  310. package/build/client/_app/immutable/nodes/1.C4eFlqSB.js.gz +0 -0
  311. package/build/client/_app/immutable/nodes/2.CdC092Za.js.br +0 -0
  312. package/build/client/_app/immutable/nodes/2.CdC092Za.js.gz +0 -0
  313. package/build/client/_app/immutable/nodes/3.Dhf4ZWW0.js.br +0 -0
  314. package/build/client/_app/immutable/nodes/3.Dhf4ZWW0.js.gz +0 -0
  315. package/build/client/_app/immutable/nodes/4.BSVqdrrD.js.br +0 -0
  316. package/build/client/_app/immutable/nodes/4.BSVqdrrD.js.gz +0 -0
  317. package/build/client/_app/immutable/nodes/5.Cfj35gpY.js.br +0 -0
  318. package/build/client/_app/immutable/nodes/5.Cfj35gpY.js.gz +0 -0
  319. package/build/client/_app/immutable/nodes/6.B3SEB_li.js.br +0 -0
  320. package/build/client/_app/immutable/nodes/6.B3SEB_li.js.gz +0 -0
  321. package/build/client/_app/immutable/nodes/7.DV8cJ1lX.js.br +0 -0
  322. package/build/client/_app/immutable/nodes/7.DV8cJ1lX.js.gz +0 -0
  323. package/build/client/_app/immutable/nodes/8.Bs362gyb.js.br +0 -0
  324. package/build/client/_app/immutable/nodes/8.Bs362gyb.js.gz +0 -0
  325. package/build/client/_app/immutable/nodes/9.Cf7_3uqT.js +0 -2
  326. package/build/client/_app/immutable/nodes/9.Cf7_3uqT.js.br +0 -0
  327. package/build/client/_app/immutable/nodes/9.Cf7_3uqT.js.gz +0 -0
  328. package/build/server/chunks/1-C4BOGoJY.js +0 -9
  329. package/build/server/chunks/6-D8xbnTSo.js +0 -9
  330. package/build/server/chunks/7-CkVK06S0.js +0 -9
  331. package/build/server/chunks/8-C8qVhrds.js +0 -9
  332. package/build/server/chunks/8-C8qVhrds.js.map +0 -1
  333. package/build/server/chunks/9-fL5zqN0T.js +0 -9
  334. package/build/server/chunks/9-fL5zqN0T.js.map +0 -1
  335. package/build/server/chunks/Button-B5dU-ntz.js.map +0 -1
  336. package/build/server/chunks/Icon-C7Ml3GX6.js.map +0 -1
  337. package/build/server/chunks/Input-CPGO0sbS.js.map +0 -1
  338. package/build/server/chunks/Pill-CcrtCejm.js.map +0 -1
  339. package/build/server/chunks/Shimmer-C5jkvGr1.js.map +0 -1
  340. package/build/server/chunks/_error.svelte-CSIxs-ab.js.map +0 -1
  341. package/build/server/chunks/_layout.svelte-noB4j-v2.js.map +0 -1
  342. package/build/server/chunks/_page.svelte-B6qyh-K-.js.map +0 -1
  343. package/build/server/chunks/_page.svelte-BUkm2304.js.map +0 -1
  344. package/build/server/chunks/_page.svelte-BV0XyYJZ.js.map +0 -1
  345. package/build/server/chunks/_page.svelte-BfB8maoc.js.map +0 -1
  346. package/build/server/chunks/_page.svelte-C60lAagP.js.map +0 -1
  347. package/build/server/chunks/_page.svelte-Dmg-RFCg.js.map +0 -1
  348. package/build/server/chunks/_page.svelte-DnTpPnPR.js.map +0 -1
  349. package/build/server/chunks/_page.svelte-DuzZr5dA.js.map +0 -1
  350. package/build/server/chunks/_server.ts-BA_uWcPw.js.map +0 -1
  351. package/build/server/chunks/_server.ts-Bjbr7glm.js.map +0 -1
  352. package/build/server/chunks/_server.ts-BrqaMMAa.js.map +0 -1
  353. package/build/server/chunks/_server.ts-Bu3s5hfv.js.map +0 -1
  354. package/build/server/chunks/_server.ts-CyjDrcZN.js.map +0 -1
  355. package/build/server/chunks/_server.ts-DZ5naqSL.js.map +0 -1
  356. package/build/server/chunks/_server.ts-DZP2lhaY.js.map +0 -1
  357. package/build/server/chunks/cache-Me3zUAaD.js.map +0 -1
  358. package/build/server/chunks/client2-DDP30_vY.js +0 -7
  359. package/build/server/chunks/events-handler-Dm1mNPQP.js +0 -20
  360. package/build/server/chunks/events-handler-Dm1mNPQP.js.map +0 -1
  361. package/build/server/chunks/pty-manager-DmNSCKAr.js.map +0 -1
  362. package/build/server/chunks/registry-Kcw2UCMv.js.map +0 -1
  363. package/build/server/chunks/root-xvQIR1Bt.js.map +0 -1
  364. package/build/server/chunks/stores-C-LqoonT.js.map +0 -1
  365. /package/build/client/_app/immutable/assets/{8.BhoBXADL.css → 10.BhoBXADL.css} +0 -0
  366. /package/build/client/_app/immutable/assets/{8.BhoBXADL.css.br → 10.BhoBXADL.css.br} +0 -0
  367. /package/build/client/_app/immutable/assets/{8.BhoBXADL.css.gz → 10.BhoBXADL.css.gz} +0 -0
@@ -0,0 +1,134 @@
1
+ // Session-Over-Sessions (SoS) types — the coordinator that merges N running
2
+ // agent sessions into one source-tagged super-session and relays messages
3
+ // between them. See docs/SESSION-OVER-SESSIONS.md.
4
+ //
5
+ // A member's `sessionKey` is exactly what the server's session-watcher adapter
6
+ // keys on: a JSONL/JSON file path for file-backed providers, or a bare session
7
+ // id for OpenCode. That lets the coordinator reuse the same watcher routing the
8
+ // WS session handler uses, covering all providers with no new watching code.
9
+
10
+ import type { SessionSource } from './generated';
11
+ import type { ConversationMessage } from './sessions';
12
+
13
+ /** An escalated relay awaiting human approve/deny (Phase 2 HITL). */
14
+ export interface PendingRelay {
15
+ createdAt: string;
16
+ expiresAt: string;
17
+ fromMemberId: string;
18
+ id: string;
19
+ text: string;
20
+ timer: null | ReturnType<typeof setTimeout>;
21
+ toMemberId: string;
22
+ }
23
+
24
+ /** A control message sent from a SoS client to the coordinator over /ws/super-session/:id. */
25
+ export type SosClientMessage =
26
+ | {
27
+ capability?: string;
28
+ provider: SessionSource;
29
+ sessionKey: string;
30
+ terminalId?: string;
31
+ type: 'member-add';
32
+ }
33
+ | { memberId: string; type: 'member-remove' }
34
+ | { relayId: string; type: 'relay-approve' }
35
+ | { relayId: string; type: 'relay-deny' }
36
+ | { text: string; toMemberId: string; type: 'relay-forward' };
37
+
38
+ /**
39
+ * Injects relay text into a Shooter-owned terminal's stdin. Supplied by
40
+ * server.ts (which owns PtyManager) so the coordinator stays free of PTY deps.
41
+ * Performs the ownership check (terminal exists + running) and returns the
42
+ * outcome.
43
+ */
44
+ export type SosInjector = (terminalId: string, text: string) => { error?: string; ok: boolean };
45
+
46
+ /** A WS listener registered against a super-session. */
47
+ export type SosListener = (msg: SosServerMessage) => void;
48
+
49
+ export interface SosMember {
50
+ /** Free-text capability tag, e.g. 'frontend' | 'backend' | '' (unused in MVP routing). */
51
+ capability: string;
52
+ /** Random hex id, primary key in sos_sessions. */
53
+ id: string;
54
+ provider: SessionSource;
55
+ registeredAt: string;
56
+ /** Watcher key: file path for file-backed providers, session id for OpenCode. */
57
+ sessionKey: string;
58
+ status: SosMemberStatus;
59
+ /** PtyManager terminal id when launched via Shooter; null for externally-observed sessions. */
60
+ terminalId: null | string;
61
+ }
62
+
63
+ // ── WebSocket protocol (/ws/super-session/:id) ──────────────────────────
64
+
65
+ /** Lifecycle status of a SoS member's underlying agent session. */
66
+ export type SosMemberStatus = 'Compacting' | 'Finished' | 'Idle' | 'Waiting' | 'Working';
67
+
68
+ /**
69
+ * A static routing rule (Phase 2). The coordinator evaluates these in ascending
70
+ * `priority` against each new member message; the first match decides the
71
+ * action. `fromMemberId` may be 'ANY'; an empty `matchPattern` matches all text.
72
+ */
73
+ export interface SosRoutingRule {
74
+ action: 'block' | 'escalate' | 'relay';
75
+ fromMemberId: string;
76
+ id: string;
77
+ matchPattern: string;
78
+ priority: number;
79
+ toMemberId: string;
80
+ }
81
+
82
+ /** A message broadcast from the coordinator to subscribed SoS clients. */
83
+ export type SosServerMessage =
84
+ | {
85
+ decision: 'approved' | 'denied' | 'expired';
86
+ relayId: string;
87
+ type: 'sos-relay-resolved';
88
+ }
89
+ | { entries: SosTranscriptEntry[]; type: 'sos-history' }
90
+ | { entry: SosTranscriptEntry; type: 'sos-message' }
91
+ | {
92
+ expiresAt: string;
93
+ fromMemberId: string;
94
+ preview: string;
95
+ relayId: string;
96
+ toMemberId: string;
97
+ type: 'sos-relay-pending';
98
+ }
99
+ | { member: SosMember; type: 'sos-member-added' }
100
+ | { memberId: string; status: SosMemberStatus; type: 'sos-member-status' }
101
+ | { memberId: string; type: 'sos-member-removed' }
102
+ | { message: string; type: 'sos-error' };
103
+
104
+ /** One message in the merged transcript, tagged with its origin member. */
105
+ export interface SosTranscriptEntry {
106
+ memberId: string;
107
+ message: ConversationMessage;
108
+ provider: SessionSource;
109
+ /** True when the coordinator injected this message (loop-guard marker). */
110
+ relayed: boolean;
111
+ }
112
+
113
+ /** A super-session: N merged agent sessions coordinated as one. */
114
+ export interface SuperSession {
115
+ createdAt: string;
116
+ id: string;
117
+ label: string;
118
+ members: SosMember[];
119
+ routingRules: SosRoutingRule[];
120
+ status: 'active' | 'archived' | 'paused';
121
+ /** Source-tagged merged transcript; in-memory ring buffer (capped). */
122
+ transcript: SosTranscriptEntry[];
123
+ }
124
+
125
+ /** Coordinator-internal runtime state for one live super-session. */
126
+ export interface SuperSessionRuntime {
127
+ /** `${fromMemberId}:${toMemberId}` -> last auto-relay epoch ms (cooldown guard). */
128
+ cooldowns: Map<string, number>;
129
+ listeners: Set<SosListener>;
130
+ /** Escalated relays awaiting human decision, keyed by relayId. */
131
+ pending: Map<string, PendingRelay>;
132
+ session: SuperSession;
133
+ unsubscribes: Map<string, () => void>;
134
+ }
@@ -80,12 +80,24 @@ export interface QuickKeysProps {
80
80
 
81
81
  // --- keyboard-shortcuts types ---
82
82
 
83
- export interface ShortcutManagerOptions {
84
- onHelp: () => void;
83
+ export interface ShareGateProps {
84
+ /** Returns an error message to display, or null on success. */
85
+ onSubmit: (password: string) => Promise<null | string>;
85
86
  }
86
87
 
87
88
  // --- xterm-wrapper types ---
88
89
 
90
+ export interface ShareSheetProps {
91
+ onClose: () => void;
92
+ open?: boolean;
93
+ shareUrl: string;
94
+ terminalId: string;
95
+ }
96
+
97
+ export interface ShortcutManagerOptions {
98
+ onHelp: () => void;
99
+ }
100
+
89
101
  export interface ShortcutsHelpProps {
90
102
  onClose: () => void;
91
103
  open: boolean;
@@ -105,11 +117,14 @@ export interface TerminalOptions {
105
117
  container: HTMLElement;
106
118
  fontSize?: number;
107
119
  getTicket: () => Promise<string>;
120
+ initialCols?: number;
121
+ initialRows?: number;
108
122
  onActivity?: (active: boolean) => void;
109
123
  onCwd?: (path: string) => void;
110
124
  onDisconnect?: () => void;
111
125
  onExit?: (code: number) => void;
112
126
  onReconnect?: () => void;
127
+ readOnly?: boolean;
113
128
  terminalId?: string;
114
129
  wsUrl: string;
115
130
  }
@@ -126,7 +141,9 @@ export interface WsTerminalInboundMessage {
126
141
  active?: boolean;
127
142
  bytes?: number;
128
143
  code?: number;
144
+ cols?: number;
129
145
  data?: string;
130
146
  path?: string;
147
+ rows?: number;
131
148
  type: string;
132
149
  }
@@ -146,6 +146,7 @@ export type WireTerminalServerMessage =
146
146
  | { bytes: number; type: 'output-dropped' }
147
147
  | { chunk: number; data: string; total: number; type: 'scrollback' }
148
148
  | { code: null | number; signal: null | string; type: 'exit' }
149
+ | { cols: number; rows: number; type: 'resize' }
149
150
  | { data: string; type: 'output' }
150
151
  | { message: string; type: 'error' };
151
152
 
@@ -10,6 +10,7 @@
10
10
  import DashboardSvg from '$lib/assets/icons/dashboard.svg?raw';
11
11
  import SettingsSvg from '$lib/assets/icons/settings.svg?raw';
12
12
  import TerminalSvg from '$lib/assets/icons/terminal.svg?raw';
13
+ import ToolSvg from '$lib/assets/icons/tool.svg?raw';
13
14
  import { Button, Icon, Pill } from '@juspay/svelte-ui-components';
14
15
  import { onMount, type Snippet } from 'svelte';
15
16
 
@@ -133,6 +134,10 @@
133
134
  <Icon svg={TerminalSvg} classes="icon-26" />
134
135
  <span>Terminals</span>
135
136
  </a>
137
+ <a href="/sos" class="tab-item" class:active={$page.url.pathname.startsWith('/sos')}>
138
+ <Icon svg={ToolSvg} classes="icon-26" />
139
+ <span>SoS</span>
140
+ </a>
136
141
  </div>
137
142
  </nav>
138
143
  </div>
@@ -191,6 +196,7 @@
191
196
  }
192
197
  .tab-item {
193
198
  display: flex;
199
+ flex: 1;
194
200
  flex-direction: column;
195
201
  align-items: center;
196
202
  justify-content: center;
@@ -199,7 +205,7 @@
199
205
  font-size: 11px;
200
206
  font-weight: 500;
201
207
  text-decoration: none;
202
- padding: 6px 36px;
208
+ padding: 6px 8px;
203
209
  border-radius: var(--radius-md);
204
210
  transition: color var(--transition-fast);
205
211
  user-select: none;
@@ -226,7 +232,8 @@
226
232
  height: 60px;
227
233
  }
228
234
  .tab-item {
229
- padding: 6px 28px;
235
+ padding: 6px 8px;
236
+ min-width: 0;
230
237
  font-size: 10px;
231
238
  gap: 3px;
232
239
  min-height: 44px;
@@ -0,0 +1,36 @@
1
+ import { validateAuth } from '$lib/modules/server/auth';
2
+ import { sosCoordinator } from '$lib/modules/server/sos/coordinator';
3
+ import { json } from '@sveltejs/kit';
4
+
5
+ import type { RequestHandler } from './$types';
6
+
7
+ /** GET /api/sos — list all super-sessions. */
8
+ export const GET: RequestHandler = ({ request }) => {
9
+ const authError = validateAuth(request);
10
+ if (authError) {
11
+ return authError;
12
+ }
13
+ return json({ superSessions: sosCoordinator.listSuperSessions() });
14
+ };
15
+
16
+ /** POST /api/sos — create a new super-session. */
17
+ export const POST: RequestHandler = async ({ request }) => {
18
+ const authError = validateAuth(request);
19
+ if (authError) {
20
+ return authError;
21
+ }
22
+ let body: unknown;
23
+ try {
24
+ body = await request.json();
25
+ } catch {
26
+ return json({ error: 'Invalid JSON in request body' }, { status: 400 });
27
+ }
28
+ if (typeof body !== 'object' || body === null) {
29
+ return json({ error: 'Invalid JSON in request body' }, { status: 400 });
30
+ }
31
+ const payload = body as { label?: unknown };
32
+ const label =
33
+ typeof payload.label === 'string' && payload.label.trim() ? payload.label.trim() : 'Untitled';
34
+ const session = sosCoordinator.createSuperSession(label);
35
+ return json(session, { status: 201 });
36
+ };
@@ -0,0 +1,55 @@
1
+ import { validateAuth } from '$lib/modules/server/auth';
2
+ import { sosCoordinator } from '$lib/modules/server/sos/coordinator';
3
+ import { json } from '@sveltejs/kit';
4
+
5
+ import type { RequestHandler } from './$types';
6
+
7
+ /** GET /api/sos/[id] — fetch one super-session (incl. members + transcript). */
8
+ export const GET: RequestHandler = ({ params, request }) => {
9
+ const authError = validateAuth(request);
10
+ if (authError) {
11
+ return authError;
12
+ }
13
+ const session = sosCoordinator.getSuperSession(params.id ?? '');
14
+ if (!session) {
15
+ return json({ error: 'Super-session not found' }, { status: 404 });
16
+ }
17
+ return json(session);
18
+ };
19
+
20
+ /** PATCH /api/sos/[id] — update lifecycle status (active | paused | archived). */
21
+ export const PATCH: RequestHandler = async ({ params, request }) => {
22
+ const authError = validateAuth(request);
23
+ if (authError) {
24
+ return authError;
25
+ }
26
+ let body: unknown;
27
+ try {
28
+ body = await request.json();
29
+ } catch {
30
+ return json({ error: 'Invalid JSON in request body' }, { status: 400 });
31
+ }
32
+ if (typeof body !== 'object' || body === null) {
33
+ return json({ error: 'Invalid JSON in request body' }, { status: 400 });
34
+ }
35
+ const payload = body as { status?: unknown };
36
+ if (payload.status !== 'active' && payload.status !== 'paused' && payload.status !== 'archived') {
37
+ return json({ error: 'status must be active | paused | archived' }, { status: 400 });
38
+ }
39
+ if (!sosCoordinator.setStatus(params.id ?? '', payload.status)) {
40
+ return json({ error: 'Super-session not found' }, { status: 404 });
41
+ }
42
+ return json({ id: params.id, status: payload.status });
43
+ };
44
+
45
+ /** DELETE /api/sos/[id] — tear down a super-session (unsubscribes all members). */
46
+ export const DELETE: RequestHandler = ({ params, request }) => {
47
+ const authError = validateAuth(request);
48
+ if (authError) {
49
+ return authError;
50
+ }
51
+ if (!sosCoordinator.deleteSuperSession(params.id ?? '')) {
52
+ return json({ error: 'Super-session not found' }, { status: 404 });
53
+ }
54
+ return json({ deleted: true });
55
+ };
@@ -0,0 +1,44 @@
1
+ import { validateAuth } from '$lib/modules/server/auth';
2
+ import { sosCoordinator } from '$lib/modules/server/sos/coordinator';
3
+ import { json } from '@sveltejs/kit';
4
+
5
+ import type { RequestHandler } from './$types';
6
+
7
+ const MAX_RELAY_TEXT = 10240; // 10 KB, same cap as /ws/session send-input
8
+
9
+ /**
10
+ * POST /api/sos/[id]/inject — human-initiated relay: inject text into a member's
11
+ * Shooter-owned terminal and record it in the merged transcript.
12
+ */
13
+ export const POST: RequestHandler = async ({ params, request }) => {
14
+ const authError = validateAuth(request);
15
+ if (authError) {
16
+ return authError;
17
+ }
18
+ let body: unknown;
19
+ try {
20
+ body = await request.json();
21
+ } catch {
22
+ return json({ error: 'Invalid JSON in request body' }, { status: 400 });
23
+ }
24
+ if (typeof body !== 'object' || body === null) {
25
+ return json({ error: 'Invalid JSON in request body' }, { status: 400 });
26
+ }
27
+ const payload = body as { text?: unknown; toMemberId?: unknown };
28
+ if (typeof payload.toMemberId !== 'string' || payload.toMemberId.length === 0) {
29
+ return json({ error: 'toMemberId is required (string)' }, { status: 400 });
30
+ }
31
+ if (typeof payload.text !== 'string' || payload.text.length === 0) {
32
+ return json({ error: 'text is required (string)' }, { status: 400 });
33
+ }
34
+ if (Buffer.byteLength(payload.text, 'utf8') > MAX_RELAY_TEXT) {
35
+ return json({ error: `text exceeds ${MAX_RELAY_TEXT} bytes` }, { status: 413 });
36
+ }
37
+
38
+ const error = sosCoordinator.relayForward(params.id ?? '', payload.toMemberId, payload.text);
39
+ if (error) {
40
+ const status = error.includes('not found') ? 404 : 400;
41
+ return json({ error }, { status });
42
+ }
43
+ return json({ ok: true });
44
+ };
@@ -0,0 +1,47 @@
1
+ import { validateAuth } from '$lib/modules/server/auth';
2
+ import { sosCoordinator } from '$lib/modules/server/sos/coordinator';
3
+ import { isValidProvider, isValidSessionKey } from '$lib/modules/server/ws/super-session-handler';
4
+ import { json } from '@sveltejs/kit';
5
+
6
+ import type { RequestHandler } from './$types';
7
+
8
+ /** POST /api/sos/[id]/members — add a member session to a super-session. */
9
+ export const POST: RequestHandler = async ({ params, request }) => {
10
+ const authError = validateAuth(request);
11
+ if (authError) {
12
+ return authError;
13
+ }
14
+ let body: unknown;
15
+ try {
16
+ body = await request.json();
17
+ } catch {
18
+ return json({ error: 'Invalid JSON in request body' }, { status: 400 });
19
+ }
20
+ if (typeof body !== 'object' || body === null) {
21
+ return json({ error: 'Invalid JSON in request body' }, { status: 400 });
22
+ }
23
+ const payload = body as {
24
+ capability?: unknown;
25
+ provider?: unknown;
26
+ sessionKey?: unknown;
27
+ terminalId?: unknown;
28
+ };
29
+
30
+ if (typeof payload.sessionKey !== 'string' || !isValidSessionKey(payload.sessionKey)) {
31
+ return json({ error: 'sessionKey must be a session id or a path under home' }, { status: 400 });
32
+ }
33
+ if (typeof payload.provider !== 'string' || !isValidProvider(payload.provider)) {
34
+ return json({ error: 'provider must be a known session source' }, { status: 400 });
35
+ }
36
+
37
+ const member = sosCoordinator.addMember(params.id ?? '', {
38
+ capability: typeof payload.capability === 'string' ? payload.capability : undefined,
39
+ provider: payload.provider,
40
+ sessionKey: payload.sessionKey,
41
+ terminalId: typeof payload.terminalId === 'string' ? payload.terminalId : null,
42
+ });
43
+ if (!member) {
44
+ return json({ error: 'Super-session not found' }, { status: 404 });
45
+ }
46
+ return json(member, { status: 201 });
47
+ };
@@ -0,0 +1,17 @@
1
+ import { validateAuth } from '$lib/modules/server/auth';
2
+ import { sosCoordinator } from '$lib/modules/server/sos/coordinator';
3
+ import { json } from '@sveltejs/kit';
4
+
5
+ import type { RequestHandler } from './$types';
6
+
7
+ /** DELETE /api/sos/[id]/members/[mid] — remove a member (unsubscribes its watcher). */
8
+ export const DELETE: RequestHandler = ({ params, request }) => {
9
+ const authError = validateAuth(request);
10
+ if (authError) {
11
+ return authError;
12
+ }
13
+ if (!sosCoordinator.removeMember(params.id ?? '', params.mid ?? '')) {
14
+ return json({ error: 'Super-session or member not found' }, { status: 404 });
15
+ }
16
+ return json({ removed: true });
17
+ };
@@ -0,0 +1,85 @@
1
+ import type { SosRoutingRule } from '$lib/types';
2
+
3
+ import { validateAuth } from '$lib/modules/server/auth';
4
+ import { sosCoordinator } from '$lib/modules/server/sos/coordinator';
5
+ import { json } from '@sveltejs/kit';
6
+ import { randomBytes } from 'crypto';
7
+
8
+ import type { RequestHandler } from './$types';
9
+
10
+ const ACTIONS = new Set(['block', 'escalate', 'relay']);
11
+
12
+ /** GET /api/sos/[id]/rules — current routing rules. */
13
+ export const GET: RequestHandler = ({ params, request }) => {
14
+ const authError = validateAuth(request);
15
+ if (authError) {
16
+ return authError;
17
+ }
18
+ const rules = sosCoordinator.getRoutingRules(params.id ?? '');
19
+ if (rules === null) {
20
+ return json({ error: 'Super-session not found' }, { status: 404 });
21
+ }
22
+ return json({ routingRules: rules });
23
+ };
24
+
25
+ /** PATCH /api/sos/[id]/rules — replace the routing rules. */
26
+ export const PATCH: RequestHandler = async ({ params, request }) => {
27
+ const authError = validateAuth(request);
28
+ if (authError) {
29
+ return authError;
30
+ }
31
+ let body: unknown;
32
+ try {
33
+ body = await request.json();
34
+ } catch {
35
+ return json({ error: 'Invalid JSON in request body' }, { status: 400 });
36
+ }
37
+ if (typeof body !== 'object' || body === null) {
38
+ return json({ error: 'Invalid JSON in request body' }, { status: 400 });
39
+ }
40
+ const payload = body as { routingRules?: unknown };
41
+ if (!Array.isArray(payload.routingRules)) {
42
+ return json({ error: 'routingRules must be an array' }, { status: 400 });
43
+ }
44
+
45
+ const rules: SosRoutingRule[] = [];
46
+ for (const raw of payload.routingRules) {
47
+ const rule = normalizeRule(raw);
48
+ if (!rule) {
49
+ return json(
50
+ { error: 'Each rule needs fromMemberId, toMemberId, and action' },
51
+ { status: 400 }
52
+ );
53
+ }
54
+ rules.push(rule);
55
+ }
56
+
57
+ const error = sosCoordinator.setRoutingRules(params.id ?? '', rules);
58
+ if (error) {
59
+ return json({ error }, { status: error.includes('not found') ? 404 : 400 });
60
+ }
61
+ return json({ routingRules: rules });
62
+ };
63
+
64
+ function normalizeRule(raw: unknown): null | SosRoutingRule {
65
+ if (typeof raw !== 'object' || raw === null) {
66
+ return null;
67
+ }
68
+ const r = raw as Record<string, unknown>;
69
+ if (
70
+ typeof r.fromMemberId !== 'string' ||
71
+ typeof r.toMemberId !== 'string' ||
72
+ typeof r.action !== 'string' ||
73
+ !ACTIONS.has(r.action)
74
+ ) {
75
+ return null;
76
+ }
77
+ return {
78
+ action: r.action as SosRoutingRule['action'],
79
+ fromMemberId: r.fromMemberId,
80
+ id: typeof r.id === 'string' && r.id ? r.id : randomBytes(6).toString('hex'),
81
+ matchPattern: typeof r.matchPattern === 'string' ? r.matchPattern : '',
82
+ priority: typeof r.priority === 'number' ? r.priority : 100,
83
+ toMemberId: r.toMemberId,
84
+ };
85
+ }
@@ -1,6 +1,9 @@
1
1
  import { validateAuth } from '$lib/modules/server/auth';
2
2
  import { ptyManager } from '$lib/modules/server/terminal/pty-manager.js';
3
+ import { resolveAccess } from '$lib/modules/server/terminal/share-auth';
4
+ import { shareStore } from '$lib/modules/server/terminal/share-store';
3
5
  import { toErrorMessage } from '$lib/modules/server/utils/error';
6
+ import { closeGuests } from '$lib/modules/server/ws/guest-registry';
4
7
  import { json } from '@sveltejs/kit';
5
8
 
6
9
  import type { RequestHandler } from './$types';
@@ -21,10 +24,11 @@ function lastScrollbackLine(scrollback: string): null | string {
21
24
  }
22
25
 
23
26
  // GET /api/terminals/:id — Get terminal details by ID
27
+ // Accepts the API key (owner) or a share session token scoped to this terminal.
24
28
  export const GET: RequestHandler = ({ params, request }) => {
25
- const authError = validateAuth(request);
26
- if (authError) {
27
- return authError;
29
+ const access = resolveAccess(request, params.id);
30
+ if (!access) {
31
+ return json({ error: 'Unauthorized' }, { status: 401 });
28
32
  }
29
33
 
30
34
  try {
@@ -37,6 +41,7 @@ export const GET: RequestHandler = ({ params, request }) => {
37
41
  return json({
38
42
  args: terminal.args,
39
43
  clientCount: terminal.clients.size,
44
+ cols: terminal.cols,
40
45
  command: terminal.command,
41
46
  createdAt: terminal.createdAt.toISOString(),
42
47
  cwd: terminal.cwd,
@@ -45,10 +50,12 @@ export const GET: RequestHandler = ({ params, request }) => {
45
50
  id: terminal.id,
46
51
  lastOutput: lastScrollbackLine(terminal.scrollback),
47
52
  pid: terminal.pid,
53
+ rows: terminal.rows,
48
54
  sessionWs: `/ws/session/${terminal.id}`,
49
55
  status: terminal.status,
50
56
  timestamp: new Date().toISOString(),
51
57
  ws: `/ws/terminal/${terminal.id}`,
58
+ ...(access.level === 'guest' ? { shareMode: access.mode } : {}),
52
59
  });
53
60
  } catch (error) {
54
61
  console.error('[terminals] Failed to get terminal:', toErrorMessage(error));
@@ -72,6 +79,8 @@ export const DELETE: RequestHandler = ({ params, request }) => {
72
79
 
73
80
  if (terminal.status === 'exited') {
74
81
  ptyManager.remove(params.id);
82
+ shareStore.deleteShare(params.id);
83
+ closeGuests(params.id);
75
84
  console.log(`[terminals] Removed exited terminal ${params.id}`);
76
85
  return json({
77
86
  removed: true,
@@ -81,6 +90,8 @@ export const DELETE: RequestHandler = ({ params, request }) => {
81
90
  }
82
91
 
83
92
  ptyManager.kill(params.id);
93
+ shareStore.deleteShare(params.id);
94
+ closeGuests(params.id);
84
95
 
85
96
  console.log(`[terminals] Killed terminal ${params.id} (pid=${terminal.pid})`);
86
97
 
@@ -1,4 +1,4 @@
1
- import { validateAuth } from '$lib/modules/server/auth';
1
+ import { resolveAccess } from '$lib/modules/server/terminal/share-auth';
2
2
  import { toErrorMessage } from '$lib/modules/server/utils/error';
3
3
  import { json } from '@sveltejs/kit';
4
4
  import { mkdirSync, writeFileSync } from 'fs';
@@ -6,10 +6,14 @@ import { mkdirSync, writeFileSync } from 'fs';
6
6
  import type { RequestHandler } from './$types';
7
7
 
8
8
  // POST /api/terminals/[id]/paste-image — Write clipboard image for a terminal
9
+ // Accepts the API key (owner) or a control-mode share token for this terminal.
9
10
  export const POST: RequestHandler = async ({ params, request }) => {
10
- const authError = validateAuth(request);
11
- if (authError) {
12
- return authError;
11
+ const access = resolveAccess(request, params.id);
12
+ if (!access) {
13
+ return json({ error: 'Unauthorized' }, { status: 401 });
14
+ }
15
+ if (access.level === 'guest' && access.mode !== 'control') {
16
+ return json({ error: 'View-only access' }, { status: 403 });
13
17
  }
14
18
 
15
19
  const terminalId = params.id;
@@ -1,15 +1,19 @@
1
- import { validateAuth } from '$lib/modules/server/auth';
2
1
  import { ptyManager } from '$lib/modules/server/terminal/pty-manager.js';
2
+ import { resolveAccess } from '$lib/modules/server/terminal/share-auth';
3
3
  import { toErrorMessage } from '$lib/modules/server/utils/error';
4
4
  import { json } from '@sveltejs/kit';
5
5
 
6
6
  import type { RequestHandler } from './$types';
7
7
 
8
8
  // POST /api/terminals/:id/resize — Resize terminal
9
+ // Accepts the API key (owner) or a control-mode share token for this terminal.
9
10
  export const POST: RequestHandler = async ({ params, request }) => {
10
- const authError = validateAuth(request);
11
- if (authError) {
12
- return authError;
11
+ const access = resolveAccess(request, params.id);
12
+ if (!access) {
13
+ return json({ error: 'Unauthorized' }, { status: 401 });
14
+ }
15
+ if (access.level === 'guest' && access.mode !== 'control') {
16
+ return json({ error: 'View-only access' }, { status: 403 });
13
17
  }
14
18
 
15
19
  let body: { cols?: number; rows?: number };