@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,79 @@
1
+ import type { Options as CLIOptions } from '$generated/types';
2
+
3
+ export { CLIRunner, createRunner, sleep } from './runner';
4
+ export type { ExitCallback, OutputCallback } from './runner';
5
+
6
+ // Types generated by type-crafter
7
+ export type { CLIOptions };
8
+
9
+ // Types not yet generated by type-crafter (contain $ref/arrays)
10
+ // TODO: Remove these once type-crafter generates them
11
+ export interface CLICommand {
12
+ args: string[];
13
+ name: string;
14
+ options: CLIOptions;
15
+ }
16
+
17
+ export interface CLIResult {
18
+ error: null | string;
19
+ exitCode: number;
20
+ output: null | string;
21
+ success: boolean;
22
+ }
23
+
24
+ export interface CLIRunnerConfig {
25
+ args: null | string[];
26
+ cols: null | number;
27
+ command: string;
28
+ cwd: null | string;
29
+ rows: null | number;
30
+ useLoginShell: boolean | null;
31
+ }
32
+
33
+ const DEFAULT_OPTIONS: CLIOptions = {
34
+ dryRun: false,
35
+ timeout: null,
36
+ verbose: false,
37
+ };
38
+
39
+ export function createCommand(name: string, args: string[] = []): CLICommand {
40
+ return {
41
+ args,
42
+ name,
43
+ options: { ...DEFAULT_OPTIONS },
44
+ };
45
+ }
46
+
47
+ export function createErrorResult(error: string, exitCode = 1): CLIResult {
48
+ return {
49
+ error,
50
+ exitCode,
51
+ output: null,
52
+ success: false,
53
+ };
54
+ }
55
+
56
+ export function createSuccessResult(output: string): CLIResult {
57
+ return {
58
+ error: null,
59
+ exitCode: 0,
60
+ output,
61
+ success: true,
62
+ };
63
+ }
64
+
65
+ export function formatCommand(command: CLICommand): string {
66
+ const parts = [command.name, ...command.args];
67
+ return parts.join(' ');
68
+ }
69
+
70
+ export function withOptions(command: CLICommand, options: Partial<CLIOptions>): CLICommand {
71
+ return {
72
+ ...command,
73
+ options: {
74
+ dryRun: options.dryRun !== undefined ? options.dryRun : command.options.dryRun,
75
+ timeout: options.timeout !== undefined ? options.timeout : command.options.timeout,
76
+ verbose: options.verbose !== undefined ? options.verbose : command.options.verbose,
77
+ },
78
+ };
79
+ }
@@ -0,0 +1,162 @@
1
+ import pty, { type IPty } from 'node-pty';
2
+
3
+ import type { CLIRunnerConfig } from './index';
4
+
5
+ export type ExitCallback = (code: number, signal?: number) => void;
6
+ export type OutputCallback = (data: string) => void;
7
+
8
+ interface InternalConfig {
9
+ args: string[];
10
+ cols: number;
11
+ command: string;
12
+ cwd: string;
13
+ env: NodeJS.ProcessEnv;
14
+ rows: number;
15
+ useLoginShell: boolean;
16
+ }
17
+
18
+ export class CLIRunner {
19
+ private config: InternalConfig;
20
+ private onExitCallback: ExitCallback | null = null;
21
+ private onOutputCallback: null | OutputCallback = null;
22
+ private process: IPty | null = null;
23
+
24
+ constructor(config: CLIRunnerConfig) {
25
+ this.config = {
26
+ args: config.args ?? [],
27
+ cols: config.cols ?? 80,
28
+ command: config.command,
29
+ cwd: config.cwd ?? process.cwd(),
30
+ env: process.env,
31
+ rows: config.rows ?? 30,
32
+ useLoginShell: config.useLoginShell ?? true,
33
+ };
34
+ }
35
+
36
+ ctrlC(): this {
37
+ return this.write('\x03');
38
+ }
39
+
40
+ ctrlD(): this {
41
+ return this.write('\x04');
42
+ }
43
+
44
+ ctrlZ(): this {
45
+ return this.write('\x1a');
46
+ }
47
+
48
+ enter(): this {
49
+ return this.write('\r');
50
+ }
51
+
52
+ escape(): this {
53
+ return this.write('\x1b');
54
+ }
55
+
56
+ isRunning(): boolean {
57
+ return this.process !== null;
58
+ }
59
+
60
+ moveDown(): this {
61
+ return this.write('\x1b[B');
62
+ }
63
+
64
+ moveLeft(): this {
65
+ return this.write('\x1b[D');
66
+ }
67
+
68
+ moveRight(): this {
69
+ return this.write('\x1b[C');
70
+ }
71
+
72
+ moveUp(): this {
73
+ return this.write('\x1b[A');
74
+ }
75
+
76
+ onExit(callback: ExitCallback): this {
77
+ this.onExitCallback = callback;
78
+ return this;
79
+ }
80
+
81
+ onOutput(callback: OutputCallback): this {
82
+ this.onOutputCallback = callback;
83
+ return this;
84
+ }
85
+
86
+ resize(cols: number, rows: number): this {
87
+ this.process?.resize(cols, rows);
88
+ return this;
89
+ }
90
+
91
+ space(): this {
92
+ return this.write(' ');
93
+ }
94
+
95
+ start(): this {
96
+ if (this.process) {
97
+ throw new Error('Process already running');
98
+ }
99
+
100
+ const { args, cols, command, cwd, env, rows, useLoginShell } = this.config;
101
+
102
+ if (useLoginShell) {
103
+ const shell = process.env.SHELL || '/bin/zsh';
104
+ const shellEscape = (arg: string): string => `'${arg.replace(/'/g, "'\\''")}'`;
105
+ const fullCommand = [command, ...args].map(shellEscape).join(' ');
106
+ this.process = pty.spawn(shell, ['-l', '-c', fullCommand], {
107
+ cols,
108
+ cwd,
109
+ env,
110
+ name: 'xterm-color',
111
+ rows,
112
+ });
113
+ } else {
114
+ this.process = pty.spawn(command, args, {
115
+ cols,
116
+ cwd,
117
+ env,
118
+ name: 'xterm-color',
119
+ rows,
120
+ });
121
+ }
122
+
123
+ this.process.onData((data) => {
124
+ this.onOutputCallback?.(data);
125
+ });
126
+
127
+ this.process.onExit(({ exitCode, signal }) => {
128
+ this.onExitCallback?.(exitCode, signal);
129
+ this.process = null;
130
+ });
131
+
132
+ return this;
133
+ }
134
+
135
+ stop(): void {
136
+ if (this.process) {
137
+ this.process.kill();
138
+ this.process = null;
139
+ }
140
+ }
141
+
142
+ tab(): this {
143
+ return this.write('\t');
144
+ }
145
+
146
+ type(text: string): this {
147
+ return this.write(text);
148
+ }
149
+
150
+ write(data: string): this {
151
+ this.process?.write(data);
152
+ return this;
153
+ }
154
+ }
155
+
156
+ export function createRunner(config: CLIRunnerConfig): CLIRunner {
157
+ return new CLIRunner(config);
158
+ }
159
+
160
+ export function sleep(ms: number): Promise<void> {
161
+ return new Promise((resolve) => setTimeout(resolve, ms));
162
+ }
@@ -0,0 +1,72 @@
1
+ import admin from 'firebase-admin';
2
+
3
+ import type { NotificationPayload } from '../apn/types.js';
4
+
5
+ let app: admin.app.App | null = null;
6
+
7
+ export function isFCMConfigured(): boolean {
8
+ return !!(
9
+ process.env.FCM_PROJECT_ID &&
10
+ process.env.FCM_CLIENT_EMAIL &&
11
+ process.env.FCM_PRIVATE_KEY
12
+ );
13
+ }
14
+
15
+ export async function sendFCMNotification(
16
+ deviceToken: string,
17
+ payload: NotificationPayload
18
+ ): Promise<{ error?: string; messageId?: string; success: boolean }> {
19
+ try {
20
+ const fcmApp = getApp();
21
+
22
+ // Use DATA-ONLY messages (not notification messages)
23
+ // This is critical: notification messages are auto-displayed by Android
24
+ // and cannot have custom action buttons. Data messages always reach
25
+ // onMessageReceived() giving the app full control.
26
+ const message: admin.messaging.Message = {
27
+ android: {
28
+ priority: 'high', // Ensures delivery even in Doze mode
29
+ ttl: 300000, // 5 minutes TTL (matches pending request expiry)
30
+ },
31
+ data: {
32
+ body: payload.body || payload.message || '',
33
+ category: payload.category ? String(payload.category) : (payload.data?.category ? String(payload.data.category) : ''),
34
+ project: payload.data?.project ? String(payload.data.project) : '',
35
+ requestId: payload.data?.requestId ? String(payload.data.requestId) : '',
36
+ source: payload.data?.source ? String(payload.data.source) : '',
37
+ timestamp: new Date().toISOString(),
38
+ title: payload.title,
39
+ toolInput: payload.data?.toolInput ? JSON.stringify(payload.data.toolInput) : '',
40
+ toolName: payload.data?.toolName ? String(payload.data.toolName) : '',
41
+ type: payload.data?.type ? String(payload.data.type) : '',
42
+ },
43
+ token: deviceToken,
44
+ };
45
+
46
+ const messageId = await admin.messaging(fcmApp).send(message);
47
+ return { messageId, success: true };
48
+ } catch (error) {
49
+ const errorMessage = error instanceof Error ? error.message : String(error);
50
+ console.error('[FCM] Send failed:', errorMessage);
51
+ return { error: errorMessage, success: false };
52
+ }
53
+ }
54
+
55
+ function getApp(): admin.app.App {
56
+ if (!app) {
57
+ const projectId = process.env.FCM_PROJECT_ID;
58
+ const clientEmail = process.env.FCM_CLIENT_EMAIL;
59
+ const privateKey = process.env.FCM_PRIVATE_KEY?.replace(/\\n/g, '\n');
60
+
61
+ if (!projectId || !clientEmail || !privateKey) {
62
+ throw new Error(
63
+ 'FCM not configured: missing FCM_PROJECT_ID, FCM_CLIENT_EMAIL, or FCM_PRIVATE_KEY'
64
+ );
65
+ }
66
+
67
+ app = admin.initializeApp({
68
+ credential: admin.credential.cert({ clientEmail, privateKey, projectId }),
69
+ });
70
+ }
71
+ return app;
72
+ }
@@ -0,0 +1,197 @@
1
+ /**
2
+ * Shared JSONL parsing utilities for Claude Code session files.
3
+ *
4
+ * Both the REST API (jsonl-reader.ts) and the live file watcher
5
+ * (session-watcher.ts) use these functions to convert raw JSONL lines
6
+ * into ConversationMessage objects. Keeping one canonical parser
7
+ * eliminates drift between the two code paths.
8
+ */
9
+
10
+ import type { ConversationMessage, MessagePart } from './types';
11
+
12
+ /**
13
+ * Internal event types that should be skipped during parsing.
14
+ * These are control/metadata entries that don't represent conversation content.
15
+ */
16
+ export const SKIP_EVENT_TYPES = new Set([
17
+ 'system',
18
+ 'config',
19
+ 'summary',
20
+ 'result',
21
+ 'heartbeat',
22
+ 'metadata',
23
+ ]);
24
+
25
+ /**
26
+ * Parse a single assistant content block into a MessagePart.
27
+ */
28
+ export function parseAssistantBlock(block: Record<string, unknown>): MessagePart | null {
29
+ if (!block || typeof block !== 'object') {
30
+ return null;
31
+ }
32
+
33
+ switch (block.type) {
34
+ case 'text':
35
+ return { content: (block.text as string) || '', type: 'text' };
36
+ case 'thinking':
37
+ return { content: (block.thinking as string) || '', type: 'thinking' };
38
+ case 'tool_use':
39
+ return {
40
+ id: (block.id as string) || '',
41
+ input: (block.input as Record<string, unknown>) || {},
42
+ toolName: (block.name as string) || 'Unknown',
43
+ type: 'tool_use',
44
+ };
45
+ default:
46
+ return null;
47
+ }
48
+ }
49
+
50
+ /**
51
+ * Parse a single JSONL line into zero or more ConversationMessage entries.
52
+ *
53
+ * For assistant entries, partial accumulation is handled by the caller
54
+ * using the assistantTurns map. When an assistant entry includes a
55
+ * stop_reason, the accumulated turn is flushed into assistantCompleted.
56
+ */
57
+ export function parseJsonlLine(
58
+ line: string,
59
+ assistantTurns: Map<string, { parts: MessagePart[]; timestamp: string }>,
60
+ messageIndex: number
61
+ ): { assistantCompleted: ConversationMessage[]; messages: ConversationMessage[] } {
62
+ const messages: ConversationMessage[] = [];
63
+ const assistantCompleted: ConversationMessage[] = [];
64
+
65
+ const entry = JSON.parse(line);
66
+ const entryType = entry.type;
67
+
68
+ // Skip known internal event types that don't represent conversation content
69
+ if (SKIP_EVENT_TYPES.has(entryType)) {
70
+ return { assistantCompleted, messages };
71
+ }
72
+
73
+ if (entryType === 'user') {
74
+ const msg = entry.message;
75
+ if (!msg?.content) {
76
+ return { assistantCompleted, messages };
77
+ }
78
+
79
+ const parts: MessagePart[] = [];
80
+ const content = Array.isArray(msg.content) ? msg.content : [msg.content];
81
+
82
+ for (const block of content) {
83
+ if (typeof block === 'string') {
84
+ parts.push({ content: block, type: 'text' });
85
+ } else if (block.type === 'text') {
86
+ parts.push({ content: block.text || '', type: 'text' });
87
+ } else if (block.type === 'tool_result') {
88
+ let output = '';
89
+ if (typeof block.content === 'string') {
90
+ output = block.content;
91
+ } else if (Array.isArray(block.content)) {
92
+ output = block.content
93
+ .filter((c: { type: string }) => c.type === 'text')
94
+ .map((c: { text: string }) => c.text)
95
+ .join('\n');
96
+ }
97
+ if (entry.toolUseResult?.content) {
98
+ const trc = entry.toolUseResult.content;
99
+ if (typeof trc === 'string') {
100
+ output = trc;
101
+ } else if (Array.isArray(trc)) {
102
+ output = trc
103
+ .filter((c: { type: string }) => c.type === 'text')
104
+ .map((c: { text: string }) => c.text)
105
+ .join('\n');
106
+ }
107
+ }
108
+ parts.push({
109
+ isError: block.is_error || false,
110
+ output: output.slice(0, 2000),
111
+ toolUseId: block.tool_use_id || '',
112
+ type: 'tool_result',
113
+ });
114
+ }
115
+ }
116
+
117
+ if (parts.length > 0 && parts.some((p) => p.type === 'text')) {
118
+ messages.push({
119
+ id: entry.uuid || `user-${messageIndex}`,
120
+ parts: parts.filter((p) => p.type === 'text'),
121
+ role: 'user',
122
+ timestamp: entry.timestamp || '',
123
+ });
124
+ }
125
+
126
+ const toolResults = parts.filter((p) => p.type === 'tool_result');
127
+ if (toolResults.length > 0) {
128
+ messages.push({
129
+ id: `tool-result-${entry.uuid || messageIndex}`,
130
+ parts: toolResults,
131
+ role: 'system',
132
+ timestamp: entry.timestamp || '',
133
+ });
134
+ }
135
+ } else if (entryType === 'assistant') {
136
+ const msg = entry.message;
137
+ if (!msg?.content) {
138
+ return { assistantCompleted, messages };
139
+ }
140
+
141
+ const content = Array.isArray(msg.content) ? msg.content : [msg.content];
142
+ const msgId = msg.id || entry.uuid;
143
+
144
+ for (const block of content) {
145
+ const part = parseAssistantBlock(block);
146
+ if (!part) {
147
+ continue;
148
+ }
149
+
150
+ if (!assistantTurns.has(msgId)) {
151
+ assistantTurns.set(msgId, { parts: [], timestamp: entry.timestamp || '' });
152
+ }
153
+ assistantTurns.get(msgId)!.parts.push(part);
154
+ }
155
+
156
+ if (msg.stop_reason) {
157
+ const turn = assistantTurns.get(msgId);
158
+ if (turn && turn.parts.length > 0) {
159
+ assistantCompleted.push({
160
+ id: msgId,
161
+ parts: turn.parts,
162
+ role: 'assistant',
163
+ timestamp: turn.timestamp,
164
+ });
165
+ assistantTurns.delete(msgId);
166
+ }
167
+ }
168
+ }
169
+
170
+ return { assistantCompleted, messages };
171
+ }
172
+
173
+ /**
174
+ * Parse raw JSONL text into ConversationMessage entries.
175
+ * Handles multi-entry assistant turns that span multiple JSONL lines.
176
+ */
177
+ export function parseJsonlText(
178
+ text: string,
179
+ assistantTurns: Map<string, { parts: MessagePart[]; timestamp: string }>,
180
+ startIndex: number
181
+ ): ConversationMessage[] {
182
+ const lines = text.split('\n').filter((line) => line.trim());
183
+ const allMessages: ConversationMessage[] = [];
184
+ let idx = startIndex;
185
+
186
+ for (const line of lines) {
187
+ try {
188
+ const { assistantCompleted, messages } = parseJsonlLine(line, assistantTurns, idx);
189
+ allMessages.push(...messages, ...assistantCompleted);
190
+ idx++;
191
+ } catch {
192
+ // Skip malformed lines
193
+ }
194
+ }
195
+
196
+ return allMessages;
197
+ }