@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,395 @@
1
+ <script lang="ts">
2
+ import type { ShareInfoResponse, ShareMode, ShareSheetProps } from '$lib/types';
3
+
4
+ import { getApiKey } from '$lib/modules/client/common';
5
+ import { Button, Input } from '@juspay/svelte-ui-components';
6
+
7
+ const { onClose, open = false, shareUrl, terminalId }: ShareSheetProps = $props();
8
+
9
+ let active = $state(false);
10
+ let currentMode = $state<null | ShareMode>(null);
11
+ let mode = $state<ShareMode>('view');
12
+ let password = $state('');
13
+ let busy = $state(false);
14
+ let errorMsg = $state<null | string>(null);
15
+ let copied = $state(false);
16
+
17
+ // Password characters avoid ambiguous glyphs (0/O, 1/l/I).
18
+ const PASSWORD_ALPHABET = 'ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz23456789';
19
+
20
+ const canSubmit = $derived(
21
+ active ? password.length === 0 || password.length >= 6 : password.length >= 6
22
+ );
23
+
24
+ $effect(() => {
25
+ if (open) {
26
+ void loadInfo();
27
+ }
28
+ });
29
+
30
+ async function loadInfo(): Promise<void> {
31
+ errorMsg = null;
32
+ copied = false;
33
+ try {
34
+ const res = await fetch(`/api/terminals/${terminalId}/share`, {
35
+ headers: { Authorization: `Bearer ${getApiKey()}` },
36
+ });
37
+ if (!res.ok) {
38
+ errorMsg = 'Failed to load share state.';
39
+ return;
40
+ }
41
+ const info = (await res.json()) as ShareInfoResponse;
42
+ active = info.active;
43
+ currentMode = info.mode ?? null;
44
+ mode = info.mode ?? 'view';
45
+ password = '';
46
+ } catch {
47
+ errorMsg = 'Failed to reach the server.';
48
+ }
49
+ }
50
+
51
+ function generatePassword(): void {
52
+ const bytes = crypto.getRandomValues(new Uint8Array(16));
53
+ password = Array.from(bytes, (b) => PASSWORD_ALPHABET[b % PASSWORD_ALPHABET.length]).join('');
54
+ }
55
+
56
+ async function saveShare(): Promise<void> {
57
+ if (busy || !canSubmit) {
58
+ return;
59
+ }
60
+ busy = true;
61
+ errorMsg = null;
62
+ try {
63
+ const res = await fetch(`/api/terminals/${terminalId}/share`, {
64
+ body: JSON.stringify({ mode, ...(password ? { password } : {}) }),
65
+ headers: {
66
+ Authorization: `Bearer ${getApiKey()}`,
67
+ 'Content-Type': 'application/json',
68
+ },
69
+ method: 'PUT',
70
+ });
71
+ if (!res.ok) {
72
+ const data = (await res.json().catch(() => ({}))) as { error?: string };
73
+ errorMsg = data.error ?? 'Failed to save share.';
74
+ return;
75
+ }
76
+ const info = (await res.json()) as ShareInfoResponse;
77
+ active = info.active;
78
+ currentMode = info.mode ?? null;
79
+ password = '';
80
+ } catch {
81
+ errorMsg = 'Failed to reach the server.';
82
+ } finally {
83
+ busy = false;
84
+ }
85
+ }
86
+
87
+ async function revokeShare(): Promise<void> {
88
+ if (busy) {
89
+ return;
90
+ }
91
+ busy = true;
92
+ errorMsg = null;
93
+ try {
94
+ const res = await fetch(`/api/terminals/${terminalId}/share`, {
95
+ headers: { Authorization: `Bearer ${getApiKey()}` },
96
+ method: 'DELETE',
97
+ });
98
+ if (!res.ok) {
99
+ errorMsg = 'Failed to revoke share.';
100
+ return;
101
+ }
102
+ active = false;
103
+ currentMode = null;
104
+ password = '';
105
+ } catch {
106
+ errorMsg = 'Failed to reach the server.';
107
+ } finally {
108
+ busy = false;
109
+ }
110
+ }
111
+
112
+ async function copyUrl(): Promise<void> {
113
+ try {
114
+ await navigator.clipboard.writeText(shareUrl);
115
+ copied = true;
116
+ setTimeout(() => {
117
+ copied = false;
118
+ }, 2000);
119
+ } catch {
120
+ errorMsg = 'Failed to copy.';
121
+ }
122
+ }
123
+ </script>
124
+
125
+ {#if open}
126
+ <div
127
+ class="share-backdrop"
128
+ onclick={onClose}
129
+ onkeydown={(e: KeyboardEvent): void => {
130
+ if (e.key === 'Escape') {
131
+ onClose();
132
+ }
133
+ }}
134
+ role="presentation"
135
+ >
136
+ <div
137
+ class="share-sheet"
138
+ onclick={(e: MouseEvent): void => {
139
+ e.stopPropagation();
140
+ }}
141
+ role="dialog"
142
+ aria-label="Share terminal"
143
+ tabindex="-1"
144
+ onkeydown={(e: KeyboardEvent): void => {
145
+ if (e.key === 'Escape') {
146
+ onClose();
147
+ }
148
+ }}
149
+ >
150
+ <div class="share-sheet-header">
151
+ <h2 class="share-sheet-title">Share terminal</h2>
152
+ <button class="share-sheet-close" onclick={onClose} aria-label="Close">&times;</button>
153
+ </div>
154
+
155
+ {#if active}
156
+ <div class="share-active-row">
157
+ <span class="share-active-dot"></span>
158
+ <span class="share-active-label">
159
+ Sharing is active ({currentMode === 'control' ? 'full control' : 'view only'})
160
+ </span>
161
+ </div>
162
+ <div class="share-url-row">
163
+ <span class="share-url">{shareUrl}</span>
164
+ <Button
165
+ classes="btn-secondary btn-sm"
166
+ onclick={(): void => {
167
+ void copyUrl();
168
+ }}
169
+ text={copied ? 'Copied' : 'Copy'}
170
+ />
171
+ </div>
172
+ {:else}
173
+ <p class="share-sheet-sub">
174
+ Anyone with this page's link and the password below can access this terminal.
175
+ </p>
176
+ {/if}
177
+
178
+ <div class="share-field">
179
+ <span class="share-field-label">Access</span>
180
+ <div class="share-mode-toggle">
181
+ <button
182
+ class="share-mode-btn {mode === 'view' ? 'share-mode-active' : ''}"
183
+ onclick={(): void => {
184
+ mode = 'view';
185
+ }}
186
+ >
187
+ View only
188
+ </button>
189
+ <button
190
+ class="share-mode-btn {mode === 'control' ? 'share-mode-active' : ''}"
191
+ onclick={(): void => {
192
+ mode = 'control';
193
+ }}
194
+ >
195
+ Full control
196
+ </button>
197
+ </div>
198
+ </div>
199
+
200
+ <div class="share-field">
201
+ <span class="share-field-label">
202
+ {active ? 'New password (leave empty to keep current)' : 'Password (min 6 chars)'}
203
+ </span>
204
+ <div class="share-password-row">
205
+ <Input
206
+ bind:value={password}
207
+ dataType="text"
208
+ placeholder="Password"
209
+ classes="share-password-input"
210
+ />
211
+ <Button classes="btn-secondary btn-sm" onclick={generatePassword} text="Generate" />
212
+ </div>
213
+ </div>
214
+
215
+ {#if errorMsg}
216
+ <p class="share-error">{errorMsg}</p>
217
+ {/if}
218
+
219
+ <div class="share-actions">
220
+ {#if active}
221
+ <Button
222
+ classes="btn-danger btn-sm"
223
+ onclick={(): void => {
224
+ void revokeShare();
225
+ }}
226
+ disabled={busy}
227
+ text="Stop sharing"
228
+ />
229
+ {/if}
230
+ <Button
231
+ classes="btn-primary btn-sm"
232
+ onclick={(): void => {
233
+ void saveShare();
234
+ }}
235
+ disabled={busy || !canSubmit}
236
+ showLoader={busy}
237
+ text={active ? 'Update' : 'Start sharing'}
238
+ />
239
+ </div>
240
+ </div>
241
+ </div>
242
+ {/if}
243
+
244
+ <style>
245
+ .share-backdrop {
246
+ position: fixed;
247
+ inset: 0;
248
+ z-index: 100;
249
+ display: flex;
250
+ align-items: center;
251
+ justify-content: center;
252
+ background: rgba(0, 0, 0, 0.5);
253
+ padding: var(--space-4);
254
+ }
255
+
256
+ .share-sheet {
257
+ display: flex;
258
+ flex-direction: column;
259
+ gap: var(--space-3);
260
+ width: 100%;
261
+ max-width: 420px;
262
+ padding: var(--space-5);
263
+ background: var(--ds-background-100);
264
+ border: 1px solid var(--border);
265
+ border-radius: var(--radius-lg);
266
+ }
267
+
268
+ .share-sheet-header {
269
+ display: flex;
270
+ align-items: center;
271
+ justify-content: space-between;
272
+ }
273
+
274
+ .share-sheet-title {
275
+ margin: 0;
276
+ font-size: var(--text-lg);
277
+ color: var(--text-primary);
278
+ }
279
+
280
+ .share-sheet-close {
281
+ background: none;
282
+ border: none;
283
+ color: var(--text-tertiary);
284
+ font-size: 22px;
285
+ cursor: pointer;
286
+ line-height: 1;
287
+ padding: 4px;
288
+ }
289
+
290
+ .share-sheet-close:hover {
291
+ color: var(--text-primary);
292
+ }
293
+
294
+ .share-sheet-sub {
295
+ margin: 0;
296
+ font-size: var(--text-sm);
297
+ color: var(--text-tertiary);
298
+ }
299
+
300
+ .share-active-row {
301
+ display: flex;
302
+ align-items: center;
303
+ gap: var(--space-2);
304
+ }
305
+
306
+ .share-active-dot {
307
+ width: 8px;
308
+ height: 8px;
309
+ border-radius: 50%;
310
+ background: var(--ds-green-500, #22c55e);
311
+ }
312
+
313
+ .share-active-label {
314
+ font-size: var(--text-sm);
315
+ color: var(--text-secondary);
316
+ }
317
+
318
+ .share-url-row {
319
+ display: flex;
320
+ align-items: center;
321
+ gap: var(--space-2);
322
+ padding: var(--space-2);
323
+ background: var(--ds-gray-200);
324
+ border-radius: var(--radius-md);
325
+ }
326
+
327
+ .share-url {
328
+ flex: 1;
329
+ font-family: var(--font-mono);
330
+ font-size: 11px;
331
+ color: var(--text-secondary);
332
+ overflow: hidden;
333
+ text-overflow: ellipsis;
334
+ white-space: nowrap;
335
+ }
336
+
337
+ .share-field {
338
+ display: flex;
339
+ flex-direction: column;
340
+ gap: var(--space-1);
341
+ }
342
+
343
+ .share-field-label {
344
+ font-size: var(--text-xs);
345
+ color: var(--text-tertiary);
346
+ }
347
+
348
+ .share-mode-toggle {
349
+ display: flex;
350
+ gap: 2px;
351
+ padding: 2px;
352
+ background: var(--ds-gray-200);
353
+ border: 1px solid var(--ds-gray-400);
354
+ border-radius: var(--radius-md);
355
+ width: fit-content;
356
+ }
357
+
358
+ .share-mode-btn {
359
+ padding: 6px 12px;
360
+ font-size: var(--text-xs);
361
+ color: var(--text-tertiary);
362
+ background: none;
363
+ border: none;
364
+ border-radius: var(--radius-sm);
365
+ cursor: pointer;
366
+ }
367
+
368
+ .share-mode-active {
369
+ background: var(--ds-background-100);
370
+ color: var(--text-primary);
371
+ }
372
+
373
+ .share-password-row {
374
+ display: flex;
375
+ align-items: center;
376
+ gap: var(--space-2);
377
+ }
378
+
379
+ .share-password-row :global(.share-password-input) {
380
+ --input-container-margin: 0;
381
+ flex: 1;
382
+ }
383
+
384
+ .share-error {
385
+ margin: 0;
386
+ font-size: var(--text-sm);
387
+ color: var(--ds-red-700, #ef4444);
388
+ }
389
+
390
+ .share-actions {
391
+ display: flex;
392
+ justify-content: flex-end;
393
+ gap: var(--space-2);
394
+ }
395
+ </style>
@@ -48,7 +48,12 @@ export async function createTerminal(options: TerminalOptions): Promise<Terminal
48
48
  term.loadAddon(fitAddon);
49
49
  term.loadAddon(new WebLinksAddon());
50
50
  term.open(options.container);
51
- fitAddon.fit();
51
+ if (options.readOnly && options.initialCols && options.initialRows) {
52
+ // View-only: render at the PTY's size (we may not resize the shared PTY).
53
+ term.resize(options.initialCols, options.initialRows);
54
+ } else {
55
+ fitAddon.fit();
56
+ }
52
57
 
53
58
  // Block browser-level Cmd/Ctrl shortcuts from reaching the PTY.
54
59
  // Allow Ctrl+<letter> terminal signals (Ctrl+C/D/L/R/Z etc.) through.
@@ -71,7 +76,7 @@ export async function createTerminal(options: TerminalOptions): Promise<Terminal
71
76
 
72
77
  // Clipboard image paste interception
73
78
  let pasteListener: ((e: ClipboardEvent) => void) | null = null;
74
- if (options.terminalId && options.apiKey) {
79
+ if (options.terminalId && options.apiKey && !options.readOnly) {
75
80
  const pasteTermId = options.terminalId;
76
81
  const pasteApiKey = options.apiKey;
77
82
 
@@ -185,6 +190,12 @@ export async function createTerminal(options: TerminalOptions): Promise<Terminal
185
190
  options.onActivity?.(msg.active ?? false);
186
191
  } else if (msg.type === 'cwd') {
187
192
  options.onCwd?.(msg.path ?? '');
193
+ } else if (msg.type === 'resize') {
194
+ // PTY was resized by another client (e.g. the owner). View-only
195
+ // terminals follow it; interactive ones are governed by their fit.
196
+ if (options.readOnly && msg.cols && msg.rows) {
197
+ term.resize(msg.cols, msg.rows);
198
+ }
188
199
  }
189
200
  };
190
201
 
@@ -205,6 +216,9 @@ export async function createTerminal(options: TerminalOptions): Promise<Terminal
205
216
 
206
217
  // Terminal input -> WebSocket
207
218
  term.onData((data) => {
219
+ if (options.readOnly) {
220
+ return;
221
+ }
208
222
  if (ws?.readyState === WebSocket.OPEN) {
209
223
  ws.send(JSON.stringify({ data, type: 'input' }));
210
224
  }
@@ -212,6 +226,9 @@ export async function createTerminal(options: TerminalOptions): Promise<Terminal
212
226
 
213
227
  // Handle resize — skip when container is hidden (display:none → size 0)
214
228
  const resizeObserver = new ResizeObserver((): void => {
229
+ if (options.readOnly) {
230
+ return; // View-only terminals keep the PTY's dimensions.
231
+ }
215
232
  if (!options.container.offsetWidth || !options.container.offsetHeight) {
216
233
  return;
217
234
  }