@juspay/shooter 1.0.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 (327) hide show
  1. package/.claude/hooks/notifier.cjs +1431 -0
  2. package/.claude/settings.json +162 -0
  3. package/README.md +515 -0
  4. package/bin/shooter.cjs +141 -0
  5. package/build/client/_app/immutable/assets/0.CM9Hl6d-.css +1 -0
  6. package/build/client/_app/immutable/assets/0.CM9Hl6d-.css.br +0 -0
  7. package/build/client/_app/immutable/assets/0.CM9Hl6d-.css.gz +0 -0
  8. package/build/client/_app/immutable/assets/2.CAShZ7lQ.css +1 -0
  9. package/build/client/_app/immutable/assets/2.CAShZ7lQ.css.br +1 -0
  10. package/build/client/_app/immutable/assets/2.CAShZ7lQ.css.gz +0 -0
  11. package/build/client/_app/immutable/assets/3.C0uFg0IS.css +1 -0
  12. package/build/client/_app/immutable/assets/3.C0uFg0IS.css.br +0 -0
  13. package/build/client/_app/immutable/assets/3.C0uFg0IS.css.gz +0 -0
  14. package/build/client/_app/immutable/assets/4.cJuCkJKZ.css +1 -0
  15. package/build/client/_app/immutable/assets/4.cJuCkJKZ.css.br +0 -0
  16. package/build/client/_app/immutable/assets/4.cJuCkJKZ.css.gz +0 -0
  17. package/build/client/_app/immutable/assets/5.DRjApZQW.css +1 -0
  18. package/build/client/_app/immutable/assets/5.DRjApZQW.css.br +0 -0
  19. package/build/client/_app/immutable/assets/5.DRjApZQW.css.gz +0 -0
  20. package/build/client/_app/immutable/assets/6.AraZrY8I.css +1 -0
  21. package/build/client/_app/immutable/assets/6.AraZrY8I.css.br +0 -0
  22. package/build/client/_app/immutable/assets/6.AraZrY8I.css.gz +0 -0
  23. package/build/client/_app/immutable/assets/7.BCJ1IuMx.css +1 -0
  24. package/build/client/_app/immutable/assets/7.BCJ1IuMx.css.br +0 -0
  25. package/build/client/_app/immutable/assets/7.BCJ1IuMx.css.gz +0 -0
  26. package/build/client/_app/immutable/assets/ChatView.CsdBAOKx.css +1 -0
  27. package/build/client/_app/immutable/assets/ChatView.CsdBAOKx.css.br +0 -0
  28. package/build/client/_app/immutable/assets/ChatView.CsdBAOKx.css.gz +0 -0
  29. package/build/client/_app/immutable/assets/markdown.B0b5w2tq.css +1 -0
  30. package/build/client/_app/immutable/assets/markdown.B0b5w2tq.css.br +0 -0
  31. package/build/client/_app/immutable/assets/markdown.B0b5w2tq.css.gz +0 -0
  32. package/build/client/_app/immutable/assets/xterm.DFuMZ0ql.css +1 -0
  33. package/build/client/_app/immutable/assets/xterm.DFuMZ0ql.css.br +0 -0
  34. package/build/client/_app/immutable/assets/xterm.DFuMZ0ql.css.gz +0 -0
  35. package/build/client/_app/immutable/chunks/BNJphC1q.js +56 -0
  36. package/build/client/_app/immutable/chunks/BNJphC1q.js.br +0 -0
  37. package/build/client/_app/immutable/chunks/BNJphC1q.js.gz +0 -0
  38. package/build/client/_app/immutable/chunks/BTGVxaYV.js +9 -0
  39. package/build/client/_app/immutable/chunks/BTGVxaYV.js.br +0 -0
  40. package/build/client/_app/immutable/chunks/BTGVxaYV.js.gz +0 -0
  41. package/build/client/_app/immutable/chunks/BlxrFPDK.js +1 -0
  42. package/build/client/_app/immutable/chunks/BlxrFPDK.js.br +0 -0
  43. package/build/client/_app/immutable/chunks/BlxrFPDK.js.gz +0 -0
  44. package/build/client/_app/immutable/chunks/Bvk7mfPM.js +1 -0
  45. package/build/client/_app/immutable/chunks/Bvk7mfPM.js.br +0 -0
  46. package/build/client/_app/immutable/chunks/Bvk7mfPM.js.gz +0 -0
  47. package/build/client/_app/immutable/chunks/CAokzuPQ.js +1 -0
  48. package/build/client/_app/immutable/chunks/CAokzuPQ.js.br +0 -0
  49. package/build/client/_app/immutable/chunks/CAokzuPQ.js.gz +0 -0
  50. package/build/client/_app/immutable/chunks/CGLrx-H5.js +1 -0
  51. package/build/client/_app/immutable/chunks/CGLrx-H5.js.br +0 -0
  52. package/build/client/_app/immutable/chunks/CGLrx-H5.js.gz +0 -0
  53. package/build/client/_app/immutable/chunks/CgCpWzEA.js +1 -0
  54. package/build/client/_app/immutable/chunks/CgCpWzEA.js.br +0 -0
  55. package/build/client/_app/immutable/chunks/CgCpWzEA.js.gz +0 -0
  56. package/build/client/_app/immutable/chunks/Cjwk_cGO.js +6 -0
  57. package/build/client/_app/immutable/chunks/Cjwk_cGO.js.br +0 -0
  58. package/build/client/_app/immutable/chunks/Cjwk_cGO.js.gz +0 -0
  59. package/build/client/_app/immutable/chunks/CtQ8EED1.js +11 -0
  60. package/build/client/_app/immutable/chunks/CtQ8EED1.js.br +0 -0
  61. package/build/client/_app/immutable/chunks/CtQ8EED1.js.gz +0 -0
  62. package/build/client/_app/immutable/chunks/DERQCisl.js +1 -0
  63. package/build/client/_app/immutable/chunks/DERQCisl.js.br +0 -0
  64. package/build/client/_app/immutable/chunks/DERQCisl.js.gz +0 -0
  65. package/build/client/_app/immutable/chunks/DKrg8TQs.js +1 -0
  66. package/build/client/_app/immutable/chunks/DKrg8TQs.js.br +0 -0
  67. package/build/client/_app/immutable/chunks/DKrg8TQs.js.gz +0 -0
  68. package/build/client/_app/immutable/chunks/DLu6yJIZ.js +1 -0
  69. package/build/client/_app/immutable/chunks/DLu6yJIZ.js.br +0 -0
  70. package/build/client/_app/immutable/chunks/DLu6yJIZ.js.gz +0 -0
  71. package/build/client/_app/immutable/chunks/Dkkpz_4D.js +126 -0
  72. package/build/client/_app/immutable/chunks/Dkkpz_4D.js.br +0 -0
  73. package/build/client/_app/immutable/chunks/Dkkpz_4D.js.gz +0 -0
  74. package/build/client/_app/immutable/chunks/DoczjQhA.js +1 -0
  75. package/build/client/_app/immutable/chunks/DoczjQhA.js.br +0 -0
  76. package/build/client/_app/immutable/chunks/DoczjQhA.js.gz +0 -0
  77. package/build/client/_app/immutable/chunks/PPVm8Dsz.js +1 -0
  78. package/build/client/_app/immutable/chunks/PPVm8Dsz.js.br +0 -0
  79. package/build/client/_app/immutable/chunks/PPVm8Dsz.js.gz +0 -0
  80. package/build/client/_app/immutable/chunks/RpcNruLP.js +2 -0
  81. package/build/client/_app/immutable/chunks/RpcNruLP.js.br +0 -0
  82. package/build/client/_app/immutable/chunks/RpcNruLP.js.gz +0 -0
  83. package/build/client/_app/immutable/chunks/a-St0Zwo.js +1 -0
  84. package/build/client/_app/immutable/chunks/a-St0Zwo.js.br +0 -0
  85. package/build/client/_app/immutable/chunks/a-St0Zwo.js.gz +0 -0
  86. package/build/client/_app/immutable/chunks/bo70OQUZ.js +1 -0
  87. package/build/client/_app/immutable/chunks/bo70OQUZ.js.br +0 -0
  88. package/build/client/_app/immutable/chunks/bo70OQUZ.js.gz +0 -0
  89. package/build/client/_app/immutable/entry/app.QvGgdvTI.js +2 -0
  90. package/build/client/_app/immutable/entry/app.QvGgdvTI.js.br +0 -0
  91. package/build/client/_app/immutable/entry/app.QvGgdvTI.js.gz +0 -0
  92. package/build/client/_app/immutable/entry/start.BntDNRMC.js +1 -0
  93. package/build/client/_app/immutable/entry/start.BntDNRMC.js.br +0 -0
  94. package/build/client/_app/immutable/entry/start.BntDNRMC.js.gz +0 -0
  95. package/build/client/_app/immutable/nodes/0.CzkdvJ7j.js +1 -0
  96. package/build/client/_app/immutable/nodes/0.CzkdvJ7j.js.br +0 -0
  97. package/build/client/_app/immutable/nodes/0.CzkdvJ7j.js.gz +0 -0
  98. package/build/client/_app/immutable/nodes/1.MG1QhfrI.js +1 -0
  99. package/build/client/_app/immutable/nodes/1.MG1QhfrI.js.br +0 -0
  100. package/build/client/_app/immutable/nodes/1.MG1QhfrI.js.gz +0 -0
  101. package/build/client/_app/immutable/nodes/2.B4MlOSh6.js +1 -0
  102. package/build/client/_app/immutable/nodes/2.B4MlOSh6.js.br +0 -0
  103. package/build/client/_app/immutable/nodes/2.B4MlOSh6.js.gz +0 -0
  104. package/build/client/_app/immutable/nodes/3.DIwYkjDn.js +3 -0
  105. package/build/client/_app/immutable/nodes/3.DIwYkjDn.js.br +0 -0
  106. package/build/client/_app/immutable/nodes/3.DIwYkjDn.js.gz +0 -0
  107. package/build/client/_app/immutable/nodes/4.D-cIe70D.js +1 -0
  108. package/build/client/_app/immutable/nodes/4.D-cIe70D.js.br +0 -0
  109. package/build/client/_app/immutable/nodes/4.D-cIe70D.js.gz +0 -0
  110. package/build/client/_app/immutable/nodes/5.D7zPRe3L.js +1 -0
  111. package/build/client/_app/immutable/nodes/5.D7zPRe3L.js.br +0 -0
  112. package/build/client/_app/immutable/nodes/5.D7zPRe3L.js.gz +0 -0
  113. package/build/client/_app/immutable/nodes/6.BB7QE48r.js +2 -0
  114. package/build/client/_app/immutable/nodes/6.BB7QE48r.js.br +0 -0
  115. package/build/client/_app/immutable/nodes/6.BB7QE48r.js.gz +0 -0
  116. package/build/client/_app/immutable/nodes/7.D8mqsrZG.js +2 -0
  117. package/build/client/_app/immutable/nodes/7.D8mqsrZG.js.br +0 -0
  118. package/build/client/_app/immutable/nodes/7.D8mqsrZG.js.gz +0 -0
  119. package/build/client/_app/version.json +1 -0
  120. package/build/client/_app/version.json.br +0 -0
  121. package/build/client/_app/version.json.gz +0 -0
  122. package/build/client/app-icon.png +0 -0
  123. package/build/client/apple-touch-icon.png +0 -0
  124. package/build/client/favicon.png +0 -0
  125. package/build/client/favicon.svg +10 -0
  126. package/build/client/favicon.svg.br +0 -0
  127. package/build/client/favicon.svg.gz +0 -0
  128. package/build/client/manifest.webmanifest +1 -0
  129. package/build/client/pwa-192x192.png +0 -0
  130. package/build/client/pwa-512x512.png +0 -0
  131. package/build/client/registerSW.js +1 -0
  132. package/build/client/registerSW.js.br +0 -0
  133. package/build/client/registerSW.js.gz +0 -0
  134. package/build/client/sw.js +222 -0
  135. package/build/client/sw.js.br +0 -0
  136. package/build/client/sw.js.gz +0 -0
  137. package/build/client/workbox-5119daf5.js +3395 -0
  138. package/build/client/workbox-5119daf5.js.br +0 -0
  139. package/build/client/workbox-5119daf5.js.gz +0 -0
  140. package/build/env.js +94 -0
  141. package/build/handler.js +1494 -0
  142. package/build/index.js +345 -0
  143. package/build/pty-holder.cjs +510 -0
  144. package/build/server/chunks/0-q2IUp76Y.js +9 -0
  145. package/build/server/chunks/0-q2IUp76Y.js.map +1 -0
  146. package/build/server/chunks/1-CU50G5wZ.js +9 -0
  147. package/build/server/chunks/1-CU50G5wZ.js.map +1 -0
  148. package/build/server/chunks/2-D01t9s8T.js +9 -0
  149. package/build/server/chunks/2-D01t9s8T.js.map +1 -0
  150. package/build/server/chunks/3-5PUQ04wC.js +9 -0
  151. package/build/server/chunks/3-5PUQ04wC.js.map +1 -0
  152. package/build/server/chunks/4-e7gywnSG.js +9 -0
  153. package/build/server/chunks/4-e7gywnSG.js.map +1 -0
  154. package/build/server/chunks/5-CA1SA6KZ.js +9 -0
  155. package/build/server/chunks/5-CA1SA6KZ.js.map +1 -0
  156. package/build/server/chunks/6-71H221sV.js +9 -0
  157. package/build/server/chunks/6-71H221sV.js.map +1 -0
  158. package/build/server/chunks/7-Bo-vmdyz.js +9 -0
  159. package/build/server/chunks/7-Bo-vmdyz.js.map +1 -0
  160. package/build/server/chunks/_layout.svelte-SFHOxs74.js +132 -0
  161. package/build/server/chunks/_layout.svelte-SFHOxs74.js.map +1 -0
  162. package/build/server/chunks/_page.svelte-B4w-2wD-.js +120 -0
  163. package/build/server/chunks/_page.svelte-B4w-2wD-.js.map +1 -0
  164. package/build/server/chunks/_page.svelte-B_qAXjkh.js +213 -0
  165. package/build/server/chunks/_page.svelte-B_qAXjkh.js.map +1 -0
  166. package/build/server/chunks/_page.svelte-CsF1_TRG.js +50 -0
  167. package/build/server/chunks/_page.svelte-CsF1_TRG.js.map +1 -0
  168. package/build/server/chunks/_page.svelte-DJC6U-P0.js +68 -0
  169. package/build/server/chunks/_page.svelte-DJC6U-P0.js.map +1 -0
  170. package/build/server/chunks/_page.svelte-DQ6HBtsz.js +407 -0
  171. package/build/server/chunks/_page.svelte-DQ6HBtsz.js.map +1 -0
  172. package/build/server/chunks/_page.svelte-LbhhjP21.js +148 -0
  173. package/build/server/chunks/_page.svelte-LbhhjP21.js.map +1 -0
  174. package/build/server/chunks/_server.ts-BL2FGb5Z.js +387 -0
  175. package/build/server/chunks/_server.ts-BL2FGb5Z.js.map +1 -0
  176. package/build/server/chunks/_server.ts-BgdjBZco.js +47 -0
  177. package/build/server/chunks/_server.ts-BgdjBZco.js.map +1 -0
  178. package/build/server/chunks/_server.ts-BihKSdj_.js +59 -0
  179. package/build/server/chunks/_server.ts-BihKSdj_.js.map +1 -0
  180. package/build/server/chunks/_server.ts-BjOJsoy4.js +63 -0
  181. package/build/server/chunks/_server.ts-BjOJsoy4.js.map +1 -0
  182. package/build/server/chunks/_server.ts-C29xzfaw.js +77 -0
  183. package/build/server/chunks/_server.ts-C29xzfaw.js.map +1 -0
  184. package/build/server/chunks/_server.ts-CPa6DgIt.js +71 -0
  185. package/build/server/chunks/_server.ts-CPa6DgIt.js.map +1 -0
  186. package/build/server/chunks/_server.ts-CbDRDIoP.js +36 -0
  187. package/build/server/chunks/_server.ts-CbDRDIoP.js.map +1 -0
  188. package/build/server/chunks/_server.ts-Cl1OEWL4.js +54 -0
  189. package/build/server/chunks/_server.ts-Cl1OEWL4.js.map +1 -0
  190. package/build/server/chunks/_server.ts-ColfDHW8.js +60 -0
  191. package/build/server/chunks/_server.ts-ColfDHW8.js.map +1 -0
  192. package/build/server/chunks/_server.ts-Cv_OrRuL.js +494 -0
  193. package/build/server/chunks/_server.ts-Cv_OrRuL.js.map +1 -0
  194. package/build/server/chunks/_server.ts-D4MNi4cD.js +25 -0
  195. package/build/server/chunks/_server.ts-D4MNi4cD.js.map +1 -0
  196. package/build/server/chunks/_server.ts-DRVbgm6k.js +125 -0
  197. package/build/server/chunks/_server.ts-DRVbgm6k.js.map +1 -0
  198. package/build/server/chunks/_server.ts-DfajWaqh.js +39 -0
  199. package/build/server/chunks/_server.ts-DfajWaqh.js.map +1 -0
  200. package/build/server/chunks/_server.ts-y9-WYDMa.js +35 -0
  201. package/build/server/chunks/_server.ts-y9-WYDMa.js.map +1 -0
  202. package/build/server/chunks/auth-CEgFis71.js +32 -0
  203. package/build/server/chunks/auth-CEgFis71.js.map +1 -0
  204. package/build/server/chunks/client-CxCatAKr.js +255 -0
  205. package/build/server/chunks/client-CxCatAKr.js.map +1 -0
  206. package/build/server/chunks/error.svelte-BqdwMWdK.js +26 -0
  207. package/build/server/chunks/error.svelte-BqdwMWdK.js.map +1 -0
  208. package/build/server/chunks/exports-CJ0Q5XmL.js +4081 -0
  209. package/build/server/chunks/exports-CJ0Q5XmL.js.map +1 -0
  210. package/build/server/chunks/index2-DAxIoAO-.js +36 -0
  211. package/build/server/chunks/index2-DAxIoAO-.js.map +1 -0
  212. package/build/server/chunks/jsonl-parser-dmZU_Hyu.js +137 -0
  213. package/build/server/chunks/jsonl-parser-dmZU_Hyu.js.map +1 -0
  214. package/build/server/chunks/library-apns-BHxLmuIx.js +104 -0
  215. package/build/server/chunks/library-apns-BHxLmuIx.js.map +1 -0
  216. package/build/server/chunks/markdown-Bxrl3cCF.js +1241 -0
  217. package/build/server/chunks/markdown-Bxrl3cCF.js.map +1 -0
  218. package/build/server/chunks/pending-requests-D8UiTw7L.js +44 -0
  219. package/build/server/chunks/pending-requests-D8UiTw7L.js.map +1 -0
  220. package/build/server/chunks/pty-manager-C0FhBiVq.js +1697 -0
  221. package/build/server/chunks/pty-manager-C0FhBiVq.js.map +1 -0
  222. package/build/server/chunks/shared-server-BDY8jh20.js +200 -0
  223. package/build/server/chunks/shared-server-BDY8jh20.js.map +1 -0
  224. package/build/server/chunks/stores-D0HorpgL.js +36 -0
  225. package/build/server/chunks/stores-D0HorpgL.js.map +1 -0
  226. package/build/server/index.js +6466 -0
  227. package/build/server/index.js.map +1 -0
  228. package/build/server/manifest.js +184 -0
  229. package/build/server/manifest.js.map +1 -0
  230. package/build/shims.js +32 -0
  231. package/package.json +94 -0
  232. package/scripts/clipboard-shims/wl-paste +48 -0
  233. package/scripts/clipboard-shims/xclip +31 -0
  234. package/scripts/install.sh +477 -0
  235. package/scripts/setup-node-pty.sh +63 -0
  236. package/scripts/setup.cjs +571 -0
  237. package/scripts/test-runner.ts +243 -0
  238. package/scripts/vercel-env-commands.sh +60 -0
  239. package/server.ts +139 -0
  240. package/src/app.css +1835 -0
  241. package/src/app.d.ts +31 -0
  242. package/src/app.html +24 -0
  243. package/src/generated/types/APN.ts +305 -0
  244. package/src/generated/types/CLI.ts +52 -0
  245. package/src/generated/types/JWT.ts +92 -0
  246. package/src/generated/types/Terminal.ts +2736 -0
  247. package/src/generated/types/index.ts +6 -0
  248. package/src/lib/assets/icons/alert-triangle.svg +5 -0
  249. package/src/lib/assets/icons/bell.svg +4 -0
  250. package/src/lib/assets/icons/check-circle.svg +4 -0
  251. package/src/lib/assets/icons/file.svg +4 -0
  252. package/src/lib/assets/icons/folder.svg +3 -0
  253. package/src/lib/assets/icons/play.svg +3 -0
  254. package/src/lib/assets/icons/refresh.svg +4 -0
  255. package/src/lib/assets/icons/settings.svg +4 -0
  256. package/src/lib/assets/icons/terminal.svg +1 -0
  257. package/src/lib/assets/icons/tool.svg +3 -0
  258. package/src/lib/assets/icons/x-circle.svg +5 -0
  259. package/src/lib/modules/client/common/Card.svelte +26 -0
  260. package/src/lib/modules/client/common/EmptyState.svelte +36 -0
  261. package/src/lib/modules/client/common/Icon.svelte +61 -0
  262. package/src/lib/modules/client/common/StatusBadge.svelte +38 -0
  263. package/src/lib/modules/client/common/cache.ts +31 -0
  264. package/src/lib/modules/client/common/config-guard.ts +18 -0
  265. package/src/lib/modules/client/common/index.ts +12 -0
  266. package/src/lib/modules/client/common/markdown.ts +23 -0
  267. package/src/lib/modules/client/common/native-bridge.ts +50 -0
  268. package/src/lib/modules/client/common/time.ts +22 -0
  269. package/src/lib/modules/client/common/tool-title.ts +28 -0
  270. package/src/lib/modules/client/terminal/ChatView.svelte +400 -0
  271. package/src/lib/modules/client/terminal/CommandPalette.svelte +60 -0
  272. package/src/lib/modules/client/terminal/ConnectionStatus.svelte +99 -0
  273. package/src/lib/modules/client/terminal/LaunchSheet.svelte +294 -0
  274. package/src/lib/modules/client/terminal/QuickKeys.svelte +71 -0
  275. package/src/lib/modules/client/terminal/ShortcutsHelp.svelte +79 -0
  276. package/src/lib/modules/client/terminal/keyboard-shortcuts.ts +70 -0
  277. package/src/lib/modules/client/terminal/xterm-wrapper.ts +243 -0
  278. package/src/lib/modules/server/apn/library-apns.ts +137 -0
  279. package/src/lib/modules/server/apn/notification-history.ts +35 -0
  280. package/src/lib/modules/server/apn/notification-sessions.ts +117 -0
  281. package/src/lib/modules/server/apn/pending-requests.ts +65 -0
  282. package/src/lib/modules/server/apn/types.ts +51 -0
  283. package/src/lib/modules/server/auth.ts +34 -0
  284. package/src/lib/modules/server/cli/index.ts +79 -0
  285. package/src/lib/modules/server/cli/runner.ts +162 -0
  286. package/src/lib/modules/server/fcm/fcm-service.ts +72 -0
  287. package/src/lib/modules/server/sessions/jsonl-parser.ts +197 -0
  288. package/src/lib/modules/server/sessions/jsonl-reader.ts +301 -0
  289. package/src/lib/modules/server/sessions/opencode-reader.ts +264 -0
  290. package/src/lib/modules/server/sessions/types.ts +53 -0
  291. package/src/lib/modules/server/terminal/holder-client.ts +273 -0
  292. package/src/lib/modules/server/terminal/opencode-watcher.ts +661 -0
  293. package/src/lib/modules/server/terminal/pty-holder.cjs +510 -0
  294. package/src/lib/modules/server/terminal/pty-manager.ts +1012 -0
  295. package/src/lib/modules/server/terminal/session-watcher.ts +320 -0
  296. package/src/lib/modules/server/terminal/terminal-store.ts +198 -0
  297. package/src/lib/modules/server/ws/events-handler.ts +73 -0
  298. package/src/lib/modules/server/ws/keepalive.ts +108 -0
  299. package/src/lib/modules/server/ws/server.ts +93 -0
  300. package/src/lib/modules/server/ws/session-handler.ts +462 -0
  301. package/src/lib/modules/server/ws/terminal-handler.ts +197 -0
  302. package/src/lib/modules/server/ws/ticket-store.ts +58 -0
  303. package/src/lib/theme.css +529 -0
  304. package/src/lib/types/config.ts +6 -0
  305. package/src/routes/+layout.svelte +218 -0
  306. package/src/routes/+page.svelte +261 -0
  307. package/src/routes/api/debug/+server.ts +33 -0
  308. package/src/routes/api/device-token/+server.ts +85 -0
  309. package/src/routes/api/health/+server.ts +100 -0
  310. package/src/routes/api/notify/+server.ts +418 -0
  311. package/src/routes/api/qr-config/+server.ts +45 -0
  312. package/src/routes/api/response/+server.ts +73 -0
  313. package/src/routes/api/sessions/+server.ts +120 -0
  314. package/src/routes/api/terminals/+server.ts +141 -0
  315. package/src/routes/api/terminals/[id]/+server.ts +75 -0
  316. package/src/routes/api/terminals/[id]/paste-image/+server.ts +61 -0
  317. package/src/routes/api/terminals/[id]/resize/+server.ts +60 -0
  318. package/src/routes/api/webhook/+server.ts +42 -0
  319. package/src/routes/api/ws-status/+server.ts +23 -0
  320. package/src/routes/api/ws-ticket/+server.ts +86 -0
  321. package/src/routes/config/+page.svelte +600 -0
  322. package/src/routes/project/+page.svelte +274 -0
  323. package/src/routes/session/[id]/+page.svelte +434 -0
  324. package/src/routes/terminals/+page.svelte +618 -0
  325. package/src/routes/terminals/[id]/+page.svelte +968 -0
  326. package/svelte.config.js +18 -0
  327. package/tsconfig.json +14 -0
@@ -0,0 +1,294 @@
1
+ <script lang="ts">
2
+ import { Banner, Button, Choicebox, Input, Select, Sheet } from '@juspay/svelte-ui-components';
3
+ import { onMount } from 'svelte';
4
+
5
+ interface Props {
6
+ apiKey: string;
7
+ onClose: () => void;
8
+ onLaunch: (response: TerminalResponse) => void;
9
+ open: boolean;
10
+ }
11
+
12
+ interface TerminalResponse {
13
+ command: string;
14
+ createdAt: string;
15
+ cwd: string;
16
+ id: string;
17
+ pid: number;
18
+ sessionWs: string;
19
+ ws: string;
20
+ }
21
+
22
+ interface Preset {
23
+ args: string[];
24
+ command: string;
25
+ label: string;
26
+ }
27
+
28
+ let { apiKey, onClose, onLaunch, open = $bindable() }: Props = $props();
29
+
30
+ const presets: Preset[] = [
31
+ { args: [], command: 'claude', label: 'Claude Code' },
32
+ { args: [], command: 'opencode', label: 'OpenCode' },
33
+ { args: [], command: 'zsh', label: 'Shell / zsh' },
34
+ { args: [], command: 'bash', label: 'Bash' },
35
+ ];
36
+
37
+ let selectedPreset = $state<number>(0);
38
+ let customCommand = $state('');
39
+ let projectPaths = $state<string[]>([]);
40
+ let selectedCwd = $state('');
41
+ let customCwd = $state('');
42
+ let launching = $state(false);
43
+ let launchError = $state('');
44
+
45
+ onMount(() => {
46
+ void fetchProjectPaths();
47
+ });
48
+
49
+ async function fetchProjectPaths(): Promise<void> {
50
+ try {
51
+ const response = await fetch('/api/sessions?limit=50&offset=0', {
52
+ headers: { Authorization: `Bearer ${apiKey}` },
53
+ });
54
+ if (!response.ok) {return;}
55
+ const data: { projects: { fullPath: string }[] } = await response.json();
56
+ const paths = data.projects
57
+ .map((p) => p.fullPath)
58
+ .filter((p): p is string => typeof p === 'string' && p.length > 0);
59
+ projectPaths = [...new Set(paths)];
60
+ if (projectPaths.length > 0 && !selectedCwd) {
61
+ selectedCwd = projectPaths[0];
62
+ }
63
+ } catch {
64
+ // Silently ignore — paths are optional
65
+ }
66
+ }
67
+
68
+ function selectPreset(index: number): void {
69
+ selectedPreset = index;
70
+ }
71
+
72
+ function isCustom(): boolean {
73
+ return presets[selectedPreset].command === '';
74
+ }
75
+
76
+ function getCommand(): string {
77
+ if (isCustom()) {return customCommand.trim().split(/\s+/)[0] || '';}
78
+ return presets[selectedPreset].command;
79
+ }
80
+
81
+ function getArgs(): string[] {
82
+ if (isCustom()) {
83
+ const parts = customCommand.trim().split(/\s+/);
84
+ return parts.slice(1);
85
+ }
86
+ return presets[selectedPreset].args;
87
+ }
88
+
89
+ function getEffectiveCwd(): string {
90
+ const custom = customCwd.trim();
91
+ if (custom) {return custom;}
92
+ if (selectedCwd) {return selectedCwd;}
93
+ return '/tmp';
94
+ }
95
+
96
+ async function handleLaunch(): Promise<void> {
97
+ const command = getCommand();
98
+ if (!command) {return;}
99
+
100
+ launching = true;
101
+ launchError = '';
102
+ try {
103
+ const response = await fetch('/api/terminals', {
104
+ body: JSON.stringify({
105
+ args: getArgs(),
106
+ command,
107
+ cwd: getEffectiveCwd() || undefined,
108
+ }),
109
+ headers: {
110
+ Authorization: `Bearer ${apiKey}`,
111
+ 'Content-Type': 'application/json',
112
+ },
113
+ method: 'POST',
114
+ });
115
+
116
+ if (!response.ok) {
117
+ const data = await response.json().catch(() => ({}));
118
+ launchError = data.error || `Failed to launch (${response.status})`;
119
+ return;
120
+ }
121
+
122
+ const result: TerminalResponse = await response.json();
123
+ onLaunch(result);
124
+ } catch {
125
+ launchError = 'Network error — is the server running?';
126
+ } finally {
127
+ launching = false;
128
+ }
129
+ }
130
+ </script>
131
+
132
+ <Sheet
133
+ bind:open
134
+ title="New Terminal"
135
+ side="bottom"
136
+ onclose={onClose}
137
+ classes="launch-sheet"
138
+ >
139
+ {#snippet content()}
140
+ <div class="launch-form">
141
+ <div class="section">
142
+ <span class="section-label">Quick Launch</span>
143
+ <div class="preset-grid">
144
+ {#each presets as preset, i (preset.label)}
145
+ <Choicebox
146
+ mode="radio"
147
+ selected={selectedPreset === i}
148
+ onclick={() => selectPreset(i)}
149
+ classes="preset-choice"
150
+ >
151
+ {preset.label}
152
+ </Choicebox>
153
+ {/each}
154
+ </div>
155
+ </div>
156
+
157
+ <div class="section">
158
+ <span class="section-label">Working Directory</span>
159
+ <Select
160
+ items={projectPaths.length > 0 ? projectPaths.map((p) => ({ id: p, label: p })) : [{ id: '', label: 'No recent projects' }]}
161
+ value={selectedCwd ? [selectedCwd] : (projectPaths.length > 0 ? [projectPaths[0]] : [''])}
162
+ placeholder="Select a project"
163
+ onchange={(value) => { selectedCwd = value[0] || ''; }}
164
+ classes="launch-select"
165
+ />
166
+ <div class="custom-cwd-group">
167
+ <Input
168
+ label="Or enter a custom path"
169
+ bind:value={customCwd}
170
+ dataType="text"
171
+ placeholder="/path/to/project"
172
+ classes="input-mono launch-input"
173
+ />
174
+ </div>
175
+ </div>
176
+
177
+ {#if isCustom()}
178
+ <div class="section">
179
+ <Input
180
+ label="Custom Command"
181
+ bind:value={customCommand}
182
+ dataType="text"
183
+ placeholder="e.g. node server.js"
184
+ classes="input-mono launch-input"
185
+ />
186
+ </div>
187
+ {/if}
188
+
189
+ <Button
190
+ classes="btn-launch"
191
+ disabled={launching || (!isCustom() ? false : !customCommand.trim())}
192
+ onclick={handleLaunch}
193
+ showLoader={launching}
194
+ text={launching ? 'Launching...' : 'Launch Terminal'}
195
+ />
196
+
197
+ {#if launchError}
198
+ <Banner text={launchError} classes="banner-error launch-error-banner" />
199
+ {/if}
200
+ </div>
201
+ {/snippet}
202
+ </Sheet>
203
+
204
+ <style>
205
+ :global(.launch-sheet) {
206
+ --sheet-background: var(--ds-gray-100);
207
+ --sheet-overlay-background: rgba(0, 0, 0, 0.6);
208
+ --sheet-overlay-z-index: 200;
209
+ --sheet-z-index: 201;
210
+ --sheet-height: auto;
211
+ --sheet-max-height: 90vh;
212
+ --sheet-box-shadow: 0 -4px 20px rgba(0, 0, 0, 0.3);
213
+ --sheet-header-padding: var(--space-4) var(--space-5);
214
+ --sheet-header-background: var(--ds-gray-100);
215
+ --sheet-header-border-bottom: none;
216
+ --sheet-title-font-size: var(--text-xl);
217
+ --sheet-title-font-weight: 600;
218
+ --sheet-title-color: var(--text-primary);
219
+ --sheet-content-padding: 0 var(--space-5) calc(var(--space-8, 32px) + env(safe-area-inset-bottom, 0px));
220
+ --sheet-close-button-color: var(--text-secondary);
221
+ --sheet-close-button-hover-background: var(--component-bg-hover);
222
+ --sheet-border: none;
223
+ }
224
+
225
+ /* Desktop: max width */
226
+ @media (min-width: 768px) {
227
+ :global(.launch-sheet) {
228
+ --sheet-max-width: 480px;
229
+ }
230
+ }
231
+
232
+ .launch-form {
233
+ display: flex;
234
+ flex-direction: column;
235
+ gap: var(--space-4);
236
+ }
237
+
238
+ .section {
239
+ display: flex;
240
+ flex-direction: column;
241
+ gap: var(--space-2);
242
+ }
243
+
244
+ .section-label {
245
+ display: block;
246
+ font-size: var(--text-xs);
247
+ font-weight: 500;
248
+ color: var(--text-secondary);
249
+ text-transform: uppercase;
250
+ letter-spacing: 0.05em;
251
+ }
252
+
253
+ .preset-grid {
254
+ display: grid;
255
+ grid-template-columns: 1fr 1fr;
256
+ gap: var(--space-2);
257
+ }
258
+
259
+ :global(.preset-choice) {
260
+ --choicebox-padding: var(--space-3) var(--space-2);
261
+ --choicebox-min-height: 48px;
262
+ --choicebox-title-font-size: var(--text-sm);
263
+ --choicebox-title-font-weight: 500;
264
+ --choicebox-indicator-size: 16px;
265
+ --choicebox-radio-inner-size: 8px;
266
+ }
267
+
268
+ .custom-cwd-group {
269
+ margin-top: var(--space-2);
270
+ }
271
+
272
+ :global(.launch-select) {
273
+ --select-height: 44px;
274
+ }
275
+
276
+ :global(.launch-input) {
277
+ --input-container-margin: 0;
278
+ }
279
+
280
+ :global(.btn-launch) {
281
+ --button-color: var(--ds-green-700);
282
+ --button-text-color: #fff;
283
+ --button-hover-color: var(--ds-green-900);
284
+ --button-hover-text-color: #fff;
285
+ --button-border-radius: var(--radius-lg);
286
+ --button-height: 48px;
287
+ --button-width: 100%;
288
+ margin-top: var(--space-2);
289
+ }
290
+
291
+ :global(.launch-error-banner) {
292
+ margin-top: var(--space-3);
293
+ }
294
+ </style>
@@ -0,0 +1,71 @@
1
+ <script lang="ts">
2
+ import { Button } from '@juspay/svelte-ui-components';
3
+
4
+ interface Props {
5
+ onKey: (key: string) => void;
6
+ }
7
+
8
+ interface QuickKey {
9
+ escape: string;
10
+ label: string;
11
+ }
12
+
13
+ const { onKey }: Props = $props();
14
+
15
+ const keys: QuickKey[] = [
16
+ { escape: '\x03', label: 'Ctrl+C' },
17
+ { escape: '\t', label: 'Tab' },
18
+ { escape: '\x1b[A', label: '\u2191' },
19
+ { escape: '\x1b[B', label: '\u2193' },
20
+ { escape: '\x1b', label: 'Esc' },
21
+ { escape: '\x04', label: 'Ctrl+D' },
22
+ { escape: '\x1a', label: 'Ctrl+Z' },
23
+ ];
24
+ </script>
25
+
26
+ <div class="quick-keys" role="toolbar" aria-label="Quick terminal keys">
27
+ {#each keys as k (k.label)}
28
+ <Button
29
+ classes="btn-quick-key"
30
+ onclick={() => { onKey(k.escape); }}
31
+ text={k.label}
32
+ />
33
+ {/each}
34
+ </div>
35
+
36
+ <style>
37
+ .quick-keys {
38
+ display: flex;
39
+ overflow-x: auto;
40
+ gap: 6px;
41
+ padding: var(--space-2) var(--space-3);
42
+ scrollbar-width: none;
43
+ -webkit-overflow-scrolling: touch;
44
+ flex-shrink: 0;
45
+ }
46
+
47
+ .quick-keys::-webkit-scrollbar {
48
+ display: none;
49
+ }
50
+
51
+ :global(.btn-quick-key) {
52
+ --button-color: #1e293b;
53
+ --button-text-color: #94a3b8;
54
+ --button-border: 1px solid var(--ds-gray-400);
55
+ --button-hover-color: #334155;
56
+ --button-hover-text-color: #e2e8f0;
57
+ --button-hover-border: 1px solid var(--ds-gray-400);
58
+ --button-height: 44px;
59
+ --button-padding: 0 var(--space-3);
60
+ --button-border-radius: var(--radius-md);
61
+ --button-font-family: var(--font-mono);
62
+ --button-font-size: var(--text-xs);
63
+ min-width: 52px;
64
+ flex-shrink: 0;
65
+ white-space: nowrap;
66
+ user-select: none;
67
+ -webkit-user-select: none;
68
+ -webkit-tap-highlight-color: transparent;
69
+ touch-action: manipulation;
70
+ }
71
+ </style>
@@ -0,0 +1,79 @@
1
+ <script lang="ts">
2
+ import { KeyboardInput, Modal } from '@juspay/svelte-ui-components';
3
+ import { getShortcutList } from './keyboard-shortcuts';
4
+
5
+ interface Props {
6
+ onClose: () => void;
7
+ open: boolean;
8
+ }
9
+
10
+ const { onClose, open }: Props = $props();
11
+ const shortcuts = getShortcutList();
12
+ </script>
13
+
14
+ {#if open}
15
+ <Modal
16
+ header={{ text: 'Keyboard Shortcuts' }}
17
+ onoverlayClick={onClose}
18
+ classes="shortcuts-modal"
19
+ >
20
+ {#snippet content()}
21
+ <div class="shortcuts-list">
22
+ {#each shortcuts as shortcut (shortcut.keys)}
23
+ <div class="shortcut-row">
24
+ <span class="shortcut-desc">{shortcut.description}</span>
25
+ <KeyboardInput keys={shortcut.keys} classes="shortcut-kbd" />
26
+ </div>
27
+ {/each}
28
+ </div>
29
+ {/snippet}
30
+ </Modal>
31
+ {/if}
32
+
33
+ <style>
34
+ :global(.shortcuts-modal) {
35
+ --modal-content-background-color: var(--component-bg);
36
+ --modal-border-radius: var(--radius-lg);
37
+ --modal-header-background-color: var(--component-bg);
38
+ --modal-header-padding: var(--space-4) var(--space-5);
39
+ --modal-header-border-bottom: 1px solid var(--border);
40
+ --header-text-size: var(--text-lg);
41
+ --modal-header-text-weight: 600;
42
+ --background-color: rgba(0, 0, 0, 0.5);
43
+ --modal-z-index: 1000;
44
+ }
45
+
46
+ :global(.shortcuts-modal .modal-content) {
47
+ max-width: 420px;
48
+ width: 90vw;
49
+ min-width: 320px;
50
+ }
51
+
52
+ .shortcuts-list {
53
+ display: flex;
54
+ flex-direction: column;
55
+ gap: var(--space-2);
56
+ padding: var(--space-4) var(--space-5);
57
+ }
58
+
59
+ .shortcut-row {
60
+ display: flex;
61
+ justify-content: space-between;
62
+ align-items: center;
63
+ padding: var(--space-2) 0;
64
+ }
65
+
66
+ .shortcut-desc {
67
+ font-size: var(--text-sm);
68
+ color: var(--text-secondary);
69
+ }
70
+
71
+ :global(.shortcut-kbd) {
72
+ --keyboard-input-key-color: var(--text-primary);
73
+ --keyboard-input-key-background: var(--ds-gray-200);
74
+ --keyboard-input-key-border: 1px solid var(--ds-gray-400);
75
+ --keyboard-input-key-box-shadow: 0 1px 0 var(--ds-gray-400);
76
+ --keyboard-input-font-family: var(--font-mono);
77
+ --keyboard-input-font-size: var(--text-xs);
78
+ }
79
+ </style>
@@ -0,0 +1,70 @@
1
+ /**
2
+ * Keyboard shortcuts for terminal pages.
3
+ *
4
+ * Platform detection: ⌘ on Mac/iPhone/iPad, Ctrl on others.
5
+ * Uses capture-phase window keydown to intercept before xterm.
6
+ */
7
+
8
+ export const isMac =
9
+ typeof navigator !== 'undefined' &&
10
+ /Mac|iPhone|iPad/.test(navigator.userAgent);
11
+
12
+ export const modLabel = isMac ? '⌘' : 'Ctrl';
13
+
14
+ export interface ShortcutAction {
15
+ action: () => void;
16
+ description: string;
17
+ key: string;
18
+ label: string;
19
+ shift?: boolean;
20
+ }
21
+
22
+ interface ShortcutManagerOptions {
23
+ onHelp: () => void;
24
+ }
25
+
26
+ /** Returns true when focus is inside a text input, textarea, or contenteditable. */
27
+ function isTextInputFocused(): boolean {
28
+ const el = document.activeElement;
29
+ if (!el) { return false; }
30
+ const tag = el.tagName;
31
+ if (tag === 'INPUT' || tag === 'TEXTAREA') { return true; }
32
+ if ((el as HTMLElement).isContentEditable) { return true; }
33
+ // xterm's terminal container
34
+ if (el.closest('.xterm')) { return true; }
35
+ return false;
36
+ }
37
+
38
+ export function createShortcutManager(options: ShortcutManagerOptions) {
39
+ function handler(e: KeyboardEvent) {
40
+ const mod = isMac ? e.metaKey : e.ctrlKey;
41
+ if (!mod) { return; }
42
+
43
+ // Don't intercept when a text input or the terminal is focused
44
+ if (isTextInputFocused()) { return; }
45
+
46
+ // Cmd+/ — show help overlay
47
+ if (e.key === '/') {
48
+ e.preventDefault();
49
+ e.stopPropagation();
50
+ options.onHelp();
51
+ return;
52
+ }
53
+ }
54
+
55
+ window.addEventListener('keydown', handler, true); // capture phase
56
+
57
+ return {
58
+ destroy() {
59
+ window.removeEventListener('keydown', handler, true);
60
+ },
61
+ };
62
+ }
63
+
64
+ /** List of all shortcuts for the help overlay. */
65
+ export function getShortcutList(): { description: string; keys: string }[] {
66
+ return [
67
+ { description: 'Command palette', keys: `${modLabel}+K` },
68
+ { description: 'Keyboard shortcuts', keys: `${modLabel}+/` },
69
+ ];
70
+ }