@juspay/shooter 1.5.0 → 1.6.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 (478) hide show
  1. package/README.md +24 -20
  2. package/bin/shooter.cjs +68 -17
  3. package/build/client/_app/immutable/assets/2.Dk9NfqnS.css +1 -0
  4. package/build/client/_app/immutable/assets/2.Dk9NfqnS.css.br +0 -0
  5. package/build/client/_app/immutable/assets/2.Dk9NfqnS.css.gz +0 -0
  6. package/build/client/_app/immutable/assets/3.DHxQoulp.css +1 -0
  7. package/build/client/_app/immutable/assets/3.DHxQoulp.css.br +0 -0
  8. package/build/client/_app/immutable/assets/3.DHxQoulp.css.gz +0 -0
  9. package/build/client/_app/immutable/assets/{3.DGDHCVnW.css → 4.D5l1JxgO.css} +1 -1
  10. package/build/client/_app/immutable/assets/4.D5l1JxgO.css.br +0 -0
  11. package/build/client/_app/immutable/assets/4.D5l1JxgO.css.gz +0 -0
  12. package/build/client/_app/immutable/assets/5.C5qz-NeI.css +1 -0
  13. package/build/client/_app/immutable/assets/5.C5qz-NeI.css.br +0 -0
  14. package/build/client/_app/immutable/assets/5.C5qz-NeI.css.gz +0 -0
  15. package/build/client/_app/immutable/chunks/1mEchsPO.js +1 -0
  16. package/build/client/_app/immutable/chunks/1mEchsPO.js.br +0 -0
  17. package/build/client/_app/immutable/chunks/1mEchsPO.js.gz +0 -0
  18. package/build/client/_app/immutable/chunks/B7X-vhXI.js +1 -0
  19. package/build/client/_app/immutable/chunks/B7X-vhXI.js.br +0 -0
  20. package/build/client/_app/immutable/chunks/B7X-vhXI.js.gz +0 -0
  21. package/build/client/_app/immutable/chunks/BRkqKgVG.js +1 -0
  22. package/build/client/_app/immutable/chunks/BRkqKgVG.js.br +0 -0
  23. package/build/client/_app/immutable/chunks/BRkqKgVG.js.gz +0 -0
  24. package/build/client/_app/immutable/chunks/BfJ-f-Tu.js +1 -0
  25. package/build/client/_app/immutable/chunks/BfJ-f-Tu.js.br +2 -0
  26. package/build/client/_app/immutable/chunks/BfJ-f-Tu.js.gz +0 -0
  27. package/build/client/_app/immutable/chunks/CGMJxf7r.js +1 -0
  28. package/build/client/_app/immutable/chunks/CGMJxf7r.js.br +0 -0
  29. package/build/client/_app/immutable/chunks/CGMJxf7r.js.gz +0 -0
  30. package/build/client/_app/immutable/chunks/{CZHsSL_X.js → CJFjKwJ7.js} +1 -1
  31. package/build/client/_app/immutable/chunks/CJFjKwJ7.js.br +0 -0
  32. package/build/client/_app/immutable/chunks/CJFjKwJ7.js.gz +0 -0
  33. package/build/client/_app/immutable/chunks/CNH2HlKj.js +20 -0
  34. package/build/client/_app/immutable/chunks/CNH2HlKj.js.br +0 -0
  35. package/build/client/_app/immutable/chunks/CNH2HlKj.js.gz +0 -0
  36. package/build/client/_app/immutable/chunks/CR6bkGJW.js +6 -0
  37. package/build/client/_app/immutable/chunks/CR6bkGJW.js.br +0 -0
  38. package/build/client/_app/immutable/chunks/CR6bkGJW.js.gz +0 -0
  39. package/build/client/_app/immutable/chunks/CVtJ6yRM.js +1 -0
  40. package/build/client/_app/immutable/chunks/CVtJ6yRM.js.br +0 -0
  41. package/build/client/_app/immutable/chunks/CVtJ6yRM.js.gz +0 -0
  42. package/build/client/_app/immutable/chunks/{CSoRdFvv.js → CaiJSUi3.js} +1 -1
  43. package/build/client/_app/immutable/chunks/CaiJSUi3.js.br +0 -0
  44. package/build/client/_app/immutable/chunks/CaiJSUi3.js.gz +0 -0
  45. package/build/client/_app/immutable/chunks/{DjsDGxCa.js → CmczWE_d.js} +4 -4
  46. package/build/client/_app/immutable/chunks/CmczWE_d.js.br +0 -0
  47. package/build/client/_app/immutable/chunks/CmczWE_d.js.gz +0 -0
  48. package/build/client/_app/immutable/chunks/{CiF38mQq.js → CqfYvnci.js} +1 -1
  49. package/build/client/_app/immutable/chunks/CqfYvnci.js.br +0 -0
  50. package/build/client/_app/immutable/chunks/CqfYvnci.js.gz +0 -0
  51. package/build/client/_app/immutable/chunks/CsgHjHGZ.js +1 -0
  52. package/build/client/_app/immutable/chunks/CsgHjHGZ.js.br +0 -0
  53. package/build/client/_app/immutable/chunks/CsgHjHGZ.js.gz +0 -0
  54. package/build/client/_app/immutable/chunks/{UJOiqIYE.js → CtrCjGZT.js} +1 -1
  55. package/build/client/_app/immutable/chunks/CtrCjGZT.js.br +0 -0
  56. package/build/client/_app/immutable/chunks/CtrCjGZT.js.gz +0 -0
  57. package/build/client/_app/immutable/chunks/DDiOVAd8.js +61 -0
  58. package/build/client/_app/immutable/chunks/DDiOVAd8.js.br +0 -0
  59. package/build/client/_app/immutable/chunks/DDiOVAd8.js.gz +0 -0
  60. package/build/client/_app/immutable/chunks/DVl0sebP.js +2 -0
  61. package/build/client/_app/immutable/chunks/DVl0sebP.js.br +0 -0
  62. package/build/client/_app/immutable/chunks/DVl0sebP.js.gz +0 -0
  63. package/build/client/_app/immutable/chunks/EhLZwqfu.js +3 -0
  64. package/build/client/_app/immutable/chunks/EhLZwqfu.js.br +0 -0
  65. package/build/client/_app/immutable/chunks/EhLZwqfu.js.gz +0 -0
  66. package/build/client/_app/immutable/chunks/gQJcRhou.js +1 -0
  67. package/build/client/_app/immutable/chunks/gQJcRhou.js.br +0 -0
  68. package/build/client/_app/immutable/chunks/gQJcRhou.js.gz +0 -0
  69. package/build/client/_app/immutable/chunks/pRcLbE0d.js +1 -0
  70. package/build/client/_app/immutable/chunks/pRcLbE0d.js.br +0 -0
  71. package/build/client/_app/immutable/chunks/pRcLbE0d.js.gz +0 -0
  72. package/build/client/_app/immutable/chunks/{CRbaG9cv.js → y_g-KC7l.js} +1 -1
  73. package/build/client/_app/immutable/chunks/y_g-KC7l.js.br +0 -0
  74. package/build/client/_app/immutable/chunks/{CRbaG9cv.js.gz → y_g-KC7l.js.gz} +0 -0
  75. package/build/client/_app/immutable/entry/app.zJvbFXsj.js +2 -0
  76. package/build/client/_app/immutable/entry/app.zJvbFXsj.js.br +0 -0
  77. package/build/client/_app/immutable/entry/app.zJvbFXsj.js.gz +0 -0
  78. package/build/client/_app/immutable/entry/start.B2Jf5iFd.js +1 -0
  79. package/build/client/_app/immutable/entry/start.B2Jf5iFd.js.br +2 -0
  80. package/build/client/_app/immutable/entry/start.B2Jf5iFd.js.gz +0 -0
  81. package/build/client/_app/immutable/nodes/0.B_E4j3MX.js +1 -0
  82. package/build/client/_app/immutable/nodes/0.B_E4j3MX.js.br +0 -0
  83. package/build/client/_app/immutable/nodes/0.B_E4j3MX.js.gz +0 -0
  84. package/build/client/_app/immutable/nodes/1.B0oFqb8X.js +1 -0
  85. package/build/client/_app/immutable/nodes/1.B0oFqb8X.js.br +0 -0
  86. package/build/client/_app/immutable/nodes/1.B0oFqb8X.js.gz +0 -0
  87. package/build/client/_app/immutable/nodes/2.Bqul0XyM.js +13 -0
  88. package/build/client/_app/immutable/nodes/2.Bqul0XyM.js.br +0 -0
  89. package/build/client/_app/immutable/nodes/2.Bqul0XyM.js.gz +0 -0
  90. package/build/client/_app/immutable/nodes/3.CTqUQKSN.js +9 -0
  91. package/build/client/_app/immutable/nodes/3.CTqUQKSN.js.br +0 -0
  92. package/build/client/_app/immutable/nodes/3.CTqUQKSN.js.gz +0 -0
  93. package/build/client/_app/immutable/nodes/4.B_pbOZoD.js +4 -0
  94. package/build/client/_app/immutable/nodes/4.B_pbOZoD.js.br +0 -0
  95. package/build/client/_app/immutable/nodes/4.B_pbOZoD.js.gz +0 -0
  96. package/build/client/_app/immutable/nodes/5.CdLPNo5-.js +1 -0
  97. package/build/client/_app/immutable/nodes/5.CdLPNo5-.js.br +0 -0
  98. package/build/client/_app/immutable/nodes/5.CdLPNo5-.js.gz +0 -0
  99. package/build/client/_app/immutable/nodes/6.BvjUfHnH.js +1 -0
  100. package/build/client/_app/immutable/nodes/6.BvjUfHnH.js.br +0 -0
  101. package/build/client/_app/immutable/nodes/6.BvjUfHnH.js.gz +0 -0
  102. package/build/client/_app/immutable/nodes/{5.DIkXVP4q.js → 7.5K7Od8ba.js} +3 -3
  103. package/build/client/_app/immutable/nodes/7.5K7Od8ba.js.br +0 -0
  104. package/build/client/_app/immutable/nodes/7.5K7Od8ba.js.gz +0 -0
  105. package/build/client/_app/immutable/nodes/8.Bs1DrW0_.js +2 -0
  106. package/build/client/_app/immutable/nodes/8.Bs1DrW0_.js.br +0 -0
  107. package/build/client/_app/immutable/nodes/8.Bs1DrW0_.js.gz +0 -0
  108. package/build/client/_app/immutable/nodes/9.1fMlGdqv.js +2 -0
  109. package/build/client/_app/immutable/nodes/9.1fMlGdqv.js.br +0 -0
  110. package/build/client/_app/immutable/nodes/9.1fMlGdqv.js.gz +0 -0
  111. package/build/client/_app/version.json +1 -1
  112. package/build/client/_app/version.json.br +0 -0
  113. package/build/client/_app/version.json.gz +0 -0
  114. package/build/server/chunks/0-e1fgD9Mi.js +23 -0
  115. package/build/server/chunks/0-e1fgD9Mi.js.map +1 -0
  116. package/build/server/chunks/1-D2_XVthm.js +9 -0
  117. package/build/server/chunks/{1-D0N7vVhH.js.map → 1-D2_XVthm.js.map} +1 -1
  118. package/build/server/chunks/2-DADX86JZ.js +21 -0
  119. package/build/server/chunks/2-DADX86JZ.js.map +1 -0
  120. package/build/server/chunks/3-CHacdiCg.js +21 -0
  121. package/build/server/chunks/3-CHacdiCg.js.map +1 -0
  122. package/build/server/chunks/4-0UE_6Ep-.js +23 -0
  123. package/build/server/chunks/4-0UE_6Ep-.js.map +1 -0
  124. package/build/server/chunks/5-BBIP1PzX.js +24 -0
  125. package/build/server/chunks/5-BBIP1PzX.js.map +1 -0
  126. package/build/server/chunks/6-CWLNQu6F.js +9 -0
  127. package/build/server/chunks/6-CWLNQu6F.js.map +1 -0
  128. package/build/server/chunks/7-DmQ3B8uy.js +9 -0
  129. package/build/server/chunks/7-DmQ3B8uy.js.map +1 -0
  130. package/build/server/chunks/8-CnFVjQtZ.js +9 -0
  131. package/build/server/chunks/8-CnFVjQtZ.js.map +1 -0
  132. package/build/server/chunks/9-Dw7-P6aF.js +9 -0
  133. package/build/server/chunks/9-Dw7-P6aF.js.map +1 -0
  134. package/build/server/chunks/{Button-Cs1aE6ka.js → Button-WKgiLWZI.js} +4 -9
  135. package/build/server/chunks/Button-WKgiLWZI.js.map +1 -0
  136. package/build/server/chunks/{EmptyState-DDFH1K8g.js → EmptyState-BUBqASsp.js} +3 -3
  137. package/build/server/chunks/{EmptyState-DDFH1K8g.js.map → EmptyState-BUBqASsp.js.map} +1 -1
  138. package/build/server/chunks/{Icon-CEUrotA6.js → Icon-BNBAg85a.js} +3 -3
  139. package/build/server/chunks/Icon-BNBAg85a.js.map +1 -0
  140. package/build/server/chunks/{Shimmer-DB8W1zt6.js → Shimmer-C4uBVwxz.js} +2 -2
  141. package/build/server/chunks/{Shimmer-DB8W1zt6.js.map → Shimmer-C4uBVwxz.js.map} +1 -1
  142. package/build/server/chunks/{_error.svelte-uCOJNxvr.js → _error.svelte-DkIwmECt.js} +5 -5
  143. package/build/server/chunks/{_error.svelte-uCOJNxvr.js.map → _error.svelte-DkIwmECt.js.map} +1 -1
  144. package/build/server/chunks/{_layout.svelte-CtWmEJwe.js → _layout.svelte-DllETxmJ.js} +13 -7
  145. package/build/server/chunks/_layout.svelte-DllETxmJ.js.map +1 -0
  146. package/build/server/chunks/_page.svelte-BZSdLKE_.js +118 -0
  147. package/build/server/chunks/_page.svelte-BZSdLKE_.js.map +1 -0
  148. package/build/server/chunks/{_page.svelte-CxWcQ0Am.js → _page.svelte-Cmuco1mC.js} +84 -199
  149. package/build/server/chunks/_page.svelte-Cmuco1mC.js.map +1 -0
  150. package/build/server/chunks/{_page.svelte-BgevQjq1.js → _page.svelte-Co5sF7W-.js} +12 -11
  151. package/build/server/chunks/{_page.svelte-BgevQjq1.js.map → _page.svelte-Co5sF7W-.js.map} +1 -1
  152. package/build/server/chunks/{_page.svelte-DO4oa_LY.js → _page.svelte-CpL3R-VI.js} +8 -8
  153. package/build/server/chunks/{_page.svelte-DO4oa_LY.js.map → _page.svelte-CpL3R-VI.js.map} +1 -1
  154. package/build/server/chunks/_page.svelte-DDSzYLUs.js +137 -0
  155. package/build/server/chunks/_page.svelte-DDSzYLUs.js.map +1 -0
  156. package/build/server/chunks/_page.svelte-JIkgFUFf.js +26 -0
  157. package/build/server/chunks/_page.svelte-JIkgFUFf.js.map +1 -0
  158. package/build/server/chunks/{_page.svelte-CVq6tRb3.js → _page.svelte-Y9-O5a5w.js} +10 -9
  159. package/build/server/chunks/_page.svelte-Y9-O5a5w.js.map +1 -0
  160. package/build/server/chunks/{_page.svelte-BcZaKdX9.js → _page.svelte-fcX09N4d.js} +9 -9
  161. package/build/server/chunks/{_page.svelte-BcZaKdX9.js.map → _page.svelte-fcX09N4d.js.map} +1 -1
  162. package/build/server/chunks/{_server.ts-DYpJImqd.js → _server.ts-0Xr2fWaq.js} +9 -5
  163. package/build/server/chunks/_server.ts-0Xr2fWaq.js.map +1 -0
  164. package/build/server/chunks/{_server.ts-CTpcLUH8.js → _server.ts-2ixC-X3K.js} +20 -5
  165. package/build/server/chunks/_server.ts-2ixC-X3K.js.map +1 -0
  166. package/build/server/chunks/{_server.ts-CAxsWKvS.js → _server.ts-40c_epk8.js} +20 -4
  167. package/build/server/chunks/_server.ts-40c_epk8.js.map +1 -0
  168. package/build/server/chunks/{_server.ts-WhTJBEJy.js → _server.ts-A9_tRR-K.js} +5 -4
  169. package/build/server/chunks/{_server.ts-WhTJBEJy.js.map → _server.ts-A9_tRR-K.js.map} +1 -1
  170. package/build/server/chunks/_server.ts-BRAzC6W1.js +98 -0
  171. package/build/server/chunks/_server.ts-BRAzC6W1.js.map +1 -0
  172. package/build/server/chunks/{_server.ts-DB_Kg97c.js → _server.ts-BScvgttw.js} +24 -4
  173. package/build/server/chunks/_server.ts-BScvgttw.js.map +1 -0
  174. package/build/server/chunks/{_server.ts-Ch-6iOHp.js → _server.ts-B__YN2kX.js} +121 -87
  175. package/build/server/chunks/_server.ts-B__YN2kX.js.map +1 -0
  176. package/build/server/chunks/{_server.ts-tSpgyl1D.js → _server.ts-Bjbr7glm.js} +4 -3
  177. package/build/server/chunks/_server.ts-Bjbr7glm.js.map +1 -0
  178. package/build/server/chunks/{_server.ts-COu0vNpd.js → _server.ts-BrqaMMAa.js} +7 -6
  179. package/build/server/chunks/_server.ts-BrqaMMAa.js.map +1 -0
  180. package/build/server/chunks/{_server.ts-vekTmWAx.js → _server.ts-BuYyCrnF.js} +6 -4
  181. package/build/server/chunks/_server.ts-BuYyCrnF.js.map +1 -0
  182. package/build/server/chunks/{_server.ts-Deok2y88.js → _server.ts-ByIrRtCx.js} +132 -76
  183. package/build/server/chunks/_server.ts-ByIrRtCx.js.map +1 -0
  184. package/build/server/chunks/{_server.ts-DYvb9ijZ.js → _server.ts-ByPExYfO.js} +4 -3
  185. package/build/server/chunks/{_server.ts-DYvb9ijZ.js.map → _server.ts-ByPExYfO.js.map} +1 -1
  186. package/build/server/chunks/_server.ts-CjpQ10xh.js +123 -0
  187. package/build/server/chunks/_server.ts-CjpQ10xh.js.map +1 -0
  188. package/build/server/chunks/_server.ts-CyjDrcZN.js +21 -0
  189. package/build/server/chunks/_server.ts-CyjDrcZN.js.map +1 -0
  190. package/build/server/chunks/{_server.ts-DV8zTCF9.js → _server.ts-DOGUMzPx.js} +4 -3
  191. package/build/server/chunks/{_server.ts-DV8zTCF9.js.map → _server.ts-DOGUMzPx.js.map} +1 -1
  192. package/build/server/chunks/_server.ts-DZvfyuNj.js +15 -0
  193. package/build/server/chunks/_server.ts-DZvfyuNj.js.map +1 -0
  194. package/build/server/chunks/{_server.ts-XzT2UHM1.js → _server.ts-DkPPTUPo.js} +4 -3
  195. package/build/server/chunks/{_server.ts-XzT2UHM1.js.map → _server.ts-DkPPTUPo.js.map} +1 -1
  196. package/build/server/chunks/{auth-DeCdZ83n.js → auth-DuunT7Cg.js} +2 -2
  197. package/build/server/chunks/{auth-DeCdZ83n.js.map → auth-DuunT7Cg.js.map} +1 -1
  198. package/build/server/chunks/{client-BdGHe_hY.js → client-DRtPDkMh.js} +4 -4
  199. package/build/server/chunks/{client-BdGHe_hY.js.map → client-DRtPDkMh.js.map} +1 -1
  200. package/build/server/chunks/client2-bqqmu0b7.js +7 -0
  201. package/build/server/chunks/{client2-CCBGA-2V.js.map → client2-bqqmu0b7.js.map} +1 -1
  202. package/build/server/chunks/close-BGlLztTb.js +192 -0
  203. package/build/server/chunks/close-BGlLztTb.js.map +1 -0
  204. package/build/server/chunks/events-handler-Dm1mNPQP.js +20 -0
  205. package/build/server/chunks/events-handler-Dm1mNPQP.js.map +1 -0
  206. package/build/server/chunks/html-FW6Ia4bL.js +8 -0
  207. package/build/server/chunks/html-FW6Ia4bL.js.map +1 -0
  208. package/build/server/chunks/{shared-server-sSGG17Df.js → index-CoD1IJuy.js} +2 -11
  209. package/build/server/chunks/index-CoD1IJuy.js.map +1 -0
  210. package/build/server/chunks/{index-DwaY1cAm.js → index-DP9bWJrR.js} +2 -2
  211. package/build/server/chunks/{index-DwaY1cAm.js.map → index-DP9bWJrR.js.map} +1 -1
  212. package/build/server/chunks/{index-server-CrDaL06Y.js → index-server-BUmV4MIG.js} +2 -2
  213. package/build/server/chunks/index-server-BUmV4MIG.js.map +1 -0
  214. package/build/server/chunks/index-server2-BJrT0wnA.js +5 -0
  215. package/build/server/chunks/index-server2-BJrT0wnA.js.map +1 -0
  216. package/build/server/chunks/{index2-CgclKpUj.js → index2-D5Y19GKR.js} +2 -2
  217. package/build/server/chunks/index2-D5Y19GKR.js.map +1 -0
  218. package/build/server/chunks/{library-apns-BqJbvSKh.js → library-apns-Cf-E-DhM.js} +5 -2
  219. package/build/server/chunks/library-apns-Cf-E-DhM.js.map +1 -0
  220. package/build/server/chunks/providers-DtstoHQ0.js +17 -0
  221. package/build/server/chunks/providers-DtstoHQ0.js.map +1 -0
  222. package/build/server/chunks/{pty-manager-BQVB7IVj.js → pty-manager-TyMUpDA9.js} +41 -9
  223. package/build/server/chunks/pty-manager-TyMUpDA9.js.map +1 -0
  224. package/build/server/chunks/{root-DDSnEAZv.js → root-CATOR_0t.js} +2 -2
  225. package/build/server/chunks/root-CATOR_0t.js.map +1 -0
  226. package/build/server/chunks/shared-server-DaWdgxVh.js +11 -0
  227. package/build/server/chunks/shared-server-DaWdgxVh.js.map +1 -0
  228. package/build/server/chunks/{state.svelte-hBbXlUak.js → state.svelte-CftllyvC.js} +3 -3
  229. package/build/server/chunks/state.svelte-CftllyvC.js.map +1 -0
  230. package/build/server/chunks/{stores-DHNzYNpX.js → stores-BjL57aOK.js} +4 -4
  231. package/build/server/chunks/{stores-DHNzYNpX.js.map → stores-BjL57aOK.js.map} +1 -1
  232. package/build/server/index.js +173 -6
  233. package/build/server/index.js.map +1 -1
  234. package/build/server/manifest.js +53 -30
  235. package/build/server/manifest.js.map +1 -1
  236. package/package.json +24 -6
  237. package/scripts/dev.mjs +361 -0
  238. package/scripts/install.sh +11 -3
  239. package/scripts/{fix-generated-types.sh → postgen-types.sh} +2 -2
  240. package/scripts/setup.cjs +219 -24
  241. package/scripts/vercel-env-commands.sh +3 -3
  242. package/server.ts +3 -3
  243. package/src/app.html +163 -0
  244. package/src/lib/modules/client/activity/ActivityFeed.svelte +279 -0
  245. package/src/lib/modules/client/activity/index.ts +8 -0
  246. package/src/lib/modules/client/activity/store.svelte.ts +478 -0
  247. package/src/lib/modules/client/activity/summarizer.ts +224 -0
  248. package/src/lib/modules/client/common/Card.svelte +2 -9
  249. package/src/lib/modules/client/common/EmptyState.svelte +2 -20
  250. package/src/lib/modules/client/common/Icon.svelte +3 -7
  251. package/src/lib/modules/client/common/StatusBadge.svelte +2 -4
  252. package/src/lib/modules/client/common/config-guard.ts +22 -2
  253. package/src/lib/modules/client/common/index.ts +1 -1
  254. package/src/lib/modules/client/common/time.ts +27 -9
  255. package/src/lib/modules/client/dashboard/DashboardCard.svelte +374 -0
  256. package/src/lib/modules/client/dashboard/DashboardView.svelte +66 -0
  257. package/src/lib/modules/client/dashboard/index.ts +12 -0
  258. package/src/lib/modules/client/dashboard/store.svelte.ts +663 -0
  259. package/src/lib/modules/client/dashboard/summarizer.ts +205 -0
  260. package/src/lib/modules/client/neurolink/fetch-proxy.ts +70 -0
  261. package/src/lib/modules/client/neurolink/provider-config.ts +111 -0
  262. package/src/lib/modules/client/terminal/ChatView.svelte +46 -43
  263. package/src/lib/modules/client/terminal/CommandPalette.svelte +3 -12
  264. package/src/lib/modules/client/terminal/ConnectionStatus.svelte +3 -6
  265. package/src/lib/modules/client/terminal/LaunchSheet.svelte +10 -21
  266. package/src/lib/modules/client/terminal/QuickKeys.svelte +4 -11
  267. package/src/lib/modules/client/terminal/ShortcutsHelp.svelte +3 -6
  268. package/src/lib/modules/client/terminal/keyboard-shortcuts.ts +5 -7
  269. package/src/lib/modules/client/terminal/xterm-wrapper.ts +27 -47
  270. package/src/lib/modules/server/apn/library-apns.ts +6 -3
  271. package/src/lib/modules/server/apn/notification-history.ts +2 -2
  272. package/src/lib/modules/server/apn/notification-sessions.ts +1 -3
  273. package/src/lib/modules/server/apn/pending-requests.ts +1 -1
  274. package/src/lib/modules/server/apn/types.ts +2 -52
  275. package/src/lib/modules/server/cli/index.ts +1 -30
  276. package/src/lib/modules/server/cli/runner.ts +7 -15
  277. package/src/lib/modules/server/fcm/fcm-service.ts +2 -2
  278. package/src/lib/modules/server/sessions/jsonl-parser.ts +97 -42
  279. package/src/lib/modules/server/sessions/jsonl-reader.ts +69 -60
  280. package/src/lib/modules/server/sessions/opencode-reader.ts +1 -1
  281. package/src/lib/modules/server/sessions/process-detector.ts +72 -31
  282. package/src/lib/modules/server/sessions/types.ts +2 -42
  283. package/src/lib/modules/server/terminal/holder-client.ts +11 -35
  284. package/src/lib/modules/server/terminal/opencode-watcher.ts +16 -24
  285. package/src/lib/modules/server/terminal/pty-manager.ts +40 -45
  286. package/src/lib/modules/server/terminal/session-watcher.ts +15 -17
  287. package/src/lib/modules/server/terminal/terminal-store.ts +1 -1
  288. package/src/lib/modules/server/ws/events-handler.ts +1 -16
  289. package/src/lib/modules/server/ws/keepalive.ts +1 -5
  290. package/src/lib/modules/server/ws/server.ts +1 -1
  291. package/src/lib/modules/server/ws/session-handler.ts +20 -86
  292. package/src/lib/modules/server/ws/terminal-handler.ts +28 -51
  293. package/src/lib/modules/server/ws/ticket-store.ts +1 -1
  294. package/src/lib/modules/shared/providers.ts +21 -0
  295. package/src/lib/types/activity.ts +18 -0
  296. package/src/lib/types/apn.ts +43 -0
  297. package/src/lib/types/cli.ts +39 -0
  298. package/src/lib/types/common.ts +39 -0
  299. package/src/lib/types/dashboard.ts +4 -0
  300. package/src/lib/types/generated/Client.ts +1656 -0
  301. package/src/{generated/types → lib/types/generated}/WsProtocol.ts +344 -2
  302. package/src/lib/types/index.ts +28 -0
  303. package/src/lib/types/neurolink.ts +4 -0
  304. package/src/lib/types/server.ts +93 -0
  305. package/src/lib/types/sessions.ts +59 -0
  306. package/src/lib/types/terminal-client.ts +132 -0
  307. package/src/lib/types/ws.ts +161 -0
  308. package/src/routes/+error.svelte +7 -2
  309. package/src/routes/+layout.server.ts +9 -0
  310. package/src/routes/+layout.svelte +36 -7
  311. package/src/routes/+page.server.ts +7 -0
  312. package/src/routes/+page.svelte +85 -35
  313. package/src/routes/activity/+page.server.ts +7 -0
  314. package/src/routes/activity/+page.svelte +58 -0
  315. package/src/routes/api/health/+server.ts +32 -19
  316. package/src/routes/api/neurolink-proxy/+server.ts +136 -0
  317. package/src/routes/api/notify/+server.ts +159 -84
  318. package/src/routes/api/sessions/+server.ts +1 -1
  319. package/src/routes/api/sessions/connect/+server.ts +10 -6
  320. package/src/routes/api/terminals/+server.ts +20 -1
  321. package/src/routes/api/terminals/[id]/+server.ts +16 -2
  322. package/src/routes/api/webhook/+server.ts +5 -33
  323. package/src/routes/api/ws-ticket/+server.ts +4 -4
  324. package/src/routes/config/+page.server.ts +9 -0
  325. package/src/routes/config/+page.svelte +118 -25
  326. package/src/routes/neurolink/+page.server.ts +10 -0
  327. package/src/routes/neurolink/+page.svelte +331 -0
  328. package/src/routes/project/+page.svelte +17 -12
  329. package/src/routes/session/[id]/+page.svelte +146 -62
  330. package/src/routes/terminals/+page.svelte +2 -2
  331. package/src/routes/terminals/[id]/+page.svelte +99 -88
  332. package/svelte.config.js +1 -3
  333. package/tsconfig.json +1 -0
  334. package/build/client/_app/immutable/assets/2.CAShZ7lQ.css +0 -1
  335. package/build/client/_app/immutable/assets/2.CAShZ7lQ.css.br +0 -1
  336. package/build/client/_app/immutable/assets/2.CAShZ7lQ.css.gz +0 -0
  337. package/build/client/_app/immutable/assets/3.DGDHCVnW.css.br +0 -0
  338. package/build/client/_app/immutable/assets/3.DGDHCVnW.css.gz +0 -0
  339. package/build/client/_app/immutable/chunks/B5NAKyil.js +0 -20
  340. package/build/client/_app/immutable/chunks/B5NAKyil.js.br +0 -0
  341. package/build/client/_app/immutable/chunks/B5NAKyil.js.gz +0 -0
  342. package/build/client/_app/immutable/chunks/B8XegpSE.js +0 -1
  343. package/build/client/_app/immutable/chunks/B8XegpSE.js.br +0 -0
  344. package/build/client/_app/immutable/chunks/B8XegpSE.js.gz +0 -0
  345. package/build/client/_app/immutable/chunks/B8zoBsv3.js +0 -6
  346. package/build/client/_app/immutable/chunks/B8zoBsv3.js.br +0 -0
  347. package/build/client/_app/immutable/chunks/B8zoBsv3.js.gz +0 -0
  348. package/build/client/_app/immutable/chunks/BIaXC2t9.js +0 -1
  349. package/build/client/_app/immutable/chunks/BIaXC2t9.js.br +0 -0
  350. package/build/client/_app/immutable/chunks/BIaXC2t9.js.gz +0 -0
  351. package/build/client/_app/immutable/chunks/BOYo8yTr.js +0 -1
  352. package/build/client/_app/immutable/chunks/BOYo8yTr.js.br +0 -0
  353. package/build/client/_app/immutable/chunks/BOYo8yTr.js.gz +0 -0
  354. package/build/client/_app/immutable/chunks/Bu1aqm5j.js +0 -1
  355. package/build/client/_app/immutable/chunks/Bu1aqm5j.js.br +0 -0
  356. package/build/client/_app/immutable/chunks/Bu1aqm5j.js.gz +0 -0
  357. package/build/client/_app/immutable/chunks/CQjSATpv.js +0 -61
  358. package/build/client/_app/immutable/chunks/CQjSATpv.js.br +0 -0
  359. package/build/client/_app/immutable/chunks/CQjSATpv.js.gz +0 -0
  360. package/build/client/_app/immutable/chunks/CRbaG9cv.js.br +0 -0
  361. package/build/client/_app/immutable/chunks/CSoRdFvv.js.br +0 -0
  362. package/build/client/_app/immutable/chunks/CSoRdFvv.js.gz +0 -0
  363. package/build/client/_app/immutable/chunks/CZHsSL_X.js.br +0 -0
  364. package/build/client/_app/immutable/chunks/CZHsSL_X.js.gz +0 -0
  365. package/build/client/_app/immutable/chunks/CiF38mQq.js.br +0 -0
  366. package/build/client/_app/immutable/chunks/CiF38mQq.js.gz +0 -0
  367. package/build/client/_app/immutable/chunks/DSU1n5N_.js +0 -1
  368. package/build/client/_app/immutable/chunks/DSU1n5N_.js.br +0 -0
  369. package/build/client/_app/immutable/chunks/DSU1n5N_.js.gz +0 -0
  370. package/build/client/_app/immutable/chunks/DVkn4r72.js +0 -1
  371. package/build/client/_app/immutable/chunks/DVkn4r72.js.br +0 -0
  372. package/build/client/_app/immutable/chunks/DVkn4r72.js.gz +0 -0
  373. package/build/client/_app/immutable/chunks/DjsDGxCa.js.br +0 -0
  374. package/build/client/_app/immutable/chunks/DjsDGxCa.js.gz +0 -0
  375. package/build/client/_app/immutable/chunks/UJOiqIYE.js.br +0 -0
  376. package/build/client/_app/immutable/chunks/UJOiqIYE.js.gz +0 -0
  377. package/build/client/_app/immutable/chunks/r0JawsZc.js +0 -2
  378. package/build/client/_app/immutable/chunks/r0JawsZc.js.br +0 -0
  379. package/build/client/_app/immutable/chunks/r0JawsZc.js.gz +0 -0
  380. package/build/client/_app/immutable/entry/app.CU7KVZja.js +0 -2
  381. package/build/client/_app/immutable/entry/app.CU7KVZja.js.br +0 -0
  382. package/build/client/_app/immutable/entry/app.CU7KVZja.js.gz +0 -0
  383. package/build/client/_app/immutable/entry/start.RAMZY19t.js +0 -1
  384. package/build/client/_app/immutable/entry/start.RAMZY19t.js.br +0 -2
  385. package/build/client/_app/immutable/entry/start.RAMZY19t.js.gz +0 -0
  386. package/build/client/_app/immutable/nodes/0.Bi3XYMSu.js +0 -1
  387. package/build/client/_app/immutable/nodes/0.Bi3XYMSu.js.br +0 -0
  388. package/build/client/_app/immutable/nodes/0.Bi3XYMSu.js.gz +0 -0
  389. package/build/client/_app/immutable/nodes/1.DTmfBFmm.js +0 -1
  390. package/build/client/_app/immutable/nodes/1.DTmfBFmm.js.br +0 -0
  391. package/build/client/_app/immutable/nodes/1.DTmfBFmm.js.gz +0 -0
  392. package/build/client/_app/immutable/nodes/2.Cm269yzt.js +0 -1
  393. package/build/client/_app/immutable/nodes/2.Cm269yzt.js.br +0 -0
  394. package/build/client/_app/immutable/nodes/2.Cm269yzt.js.gz +0 -0
  395. package/build/client/_app/immutable/nodes/3.3yohCM25.js +0 -3
  396. package/build/client/_app/immutable/nodes/3.3yohCM25.js.br +0 -0
  397. package/build/client/_app/immutable/nodes/3.3yohCM25.js.gz +0 -0
  398. package/build/client/_app/immutable/nodes/4.C25c5hMg.js +0 -1
  399. package/build/client/_app/immutable/nodes/4.C25c5hMg.js.br +0 -0
  400. package/build/client/_app/immutable/nodes/4.C25c5hMg.js.gz +0 -0
  401. package/build/client/_app/immutable/nodes/5.DIkXVP4q.js.br +0 -0
  402. package/build/client/_app/immutable/nodes/5.DIkXVP4q.js.gz +0 -0
  403. package/build/client/_app/immutable/nodes/6.BPL-HzUX.js +0 -2
  404. package/build/client/_app/immutable/nodes/6.BPL-HzUX.js.br +0 -0
  405. package/build/client/_app/immutable/nodes/6.BPL-HzUX.js.gz +0 -0
  406. package/build/client/_app/immutable/nodes/7.IgEqce53.js +0 -2
  407. package/build/client/_app/immutable/nodes/7.IgEqce53.js.br +0 -0
  408. package/build/client/_app/immutable/nodes/7.IgEqce53.js.gz +0 -0
  409. package/build/server/chunks/0-DiORznXb.js +0 -9
  410. package/build/server/chunks/0-DiORznXb.js.map +0 -1
  411. package/build/server/chunks/1-D0N7vVhH.js +0 -9
  412. package/build/server/chunks/2-DfSav7a7.js +0 -9
  413. package/build/server/chunks/2-DfSav7a7.js.map +0 -1
  414. package/build/server/chunks/3-Ck7ewhOX.js +0 -9
  415. package/build/server/chunks/3-Ck7ewhOX.js.map +0 -1
  416. package/build/server/chunks/4-DV5MZUz_.js +0 -9
  417. package/build/server/chunks/4-DV5MZUz_.js.map +0 -1
  418. package/build/server/chunks/5-DJhoAjb0.js +0 -9
  419. package/build/server/chunks/5-DJhoAjb0.js.map +0 -1
  420. package/build/server/chunks/6-Cp8CzYbr.js +0 -9
  421. package/build/server/chunks/6-Cp8CzYbr.js.map +0 -1
  422. package/build/server/chunks/7-BA4xzUj3.js +0 -9
  423. package/build/server/chunks/7-BA4xzUj3.js.map +0 -1
  424. package/build/server/chunks/Button-Cs1aE6ka.js.map +0 -1
  425. package/build/server/chunks/Icon-CEUrotA6.js.map +0 -1
  426. package/build/server/chunks/_layout.svelte-CtWmEJwe.js.map +0 -1
  427. package/build/server/chunks/_page.svelte-BdYynOck.js +0 -85
  428. package/build/server/chunks/_page.svelte-BdYynOck.js.map +0 -1
  429. package/build/server/chunks/_page.svelte-CVq6tRb3.js.map +0 -1
  430. package/build/server/chunks/_page.svelte-CxWcQ0Am.js.map +0 -1
  431. package/build/server/chunks/_server.ts-BStnNIcq.js +0 -34
  432. package/build/server/chunks/_server.ts-BStnNIcq.js.map +0 -1
  433. package/build/server/chunks/_server.ts-CAxsWKvS.js.map +0 -1
  434. package/build/server/chunks/_server.ts-COu0vNpd.js.map +0 -1
  435. package/build/server/chunks/_server.ts-CTpcLUH8.js.map +0 -1
  436. package/build/server/chunks/_server.ts-Cf84YIaW.js +0 -25
  437. package/build/server/chunks/_server.ts-Cf84YIaW.js.map +0 -1
  438. package/build/server/chunks/_server.ts-Ch-6iOHp.js.map +0 -1
  439. package/build/server/chunks/_server.ts-CtH0dhUp.js +0 -71
  440. package/build/server/chunks/_server.ts-CtH0dhUp.js.map +0 -1
  441. package/build/server/chunks/_server.ts-DB_Kg97c.js.map +0 -1
  442. package/build/server/chunks/_server.ts-DYpJImqd.js.map +0 -1
  443. package/build/server/chunks/_server.ts-Deok2y88.js.map +0 -1
  444. package/build/server/chunks/_server.ts-tSpgyl1D.js.map +0 -1
  445. package/build/server/chunks/_server.ts-vekTmWAx.js.map +0 -1
  446. package/build/server/chunks/client2-CCBGA-2V.js +0 -7
  447. package/build/server/chunks/index-server-CrDaL06Y.js.map +0 -1
  448. package/build/server/chunks/index2-CgclKpUj.js.map +0 -1
  449. package/build/server/chunks/library-apns-BqJbvSKh.js.map +0 -1
  450. package/build/server/chunks/pty-manager-BQVB7IVj.js.map +0 -1
  451. package/build/server/chunks/root-DDSnEAZv.js.map +0 -1
  452. package/build/server/chunks/shared-server-sSGG17Df.js.map +0 -1
  453. package/build/server/chunks/state.svelte-hBbXlUak.js.map +0 -1
  454. package/src/generated/types/Client.ts +0 -589
  455. package/src/lib/types/config.ts +0 -1
  456. /package/build/client/_app/immutable/assets/{4.BFUut--w.css → 6.BFUut--w.css} +0 -0
  457. /package/build/client/_app/immutable/assets/{4.BFUut--w.css.br → 6.BFUut--w.css.br} +0 -0
  458. /package/build/client/_app/immutable/assets/{4.BFUut--w.css.gz → 6.BFUut--w.css.gz} +0 -0
  459. /package/build/client/_app/immutable/assets/{5.BTOx7yt7.css → 7.BTOx7yt7.css} +0 -0
  460. /package/build/client/_app/immutable/assets/{5.BTOx7yt7.css.br → 7.BTOx7yt7.css.br} +0 -0
  461. /package/build/client/_app/immutable/assets/{5.BTOx7yt7.css.gz → 7.BTOx7yt7.css.gz} +0 -0
  462. /package/build/client/_app/immutable/assets/{6.eZGZN-BF.css → 8.eZGZN-BF.css} +0 -0
  463. /package/build/client/_app/immutable/assets/{6.eZGZN-BF.css.br → 8.eZGZN-BF.css.br} +0 -0
  464. /package/build/client/_app/immutable/assets/{6.eZGZN-BF.css.gz → 8.eZGZN-BF.css.gz} +0 -0
  465. /package/build/client/_app/immutable/assets/{7.DwS5ZHBh.css → 9.DwS5ZHBh.css} +0 -0
  466. /package/build/client/_app/immutable/assets/{7.DwS5ZHBh.css.br → 9.DwS5ZHBh.css.br} +0 -0
  467. /package/build/client/_app/immutable/assets/{7.DwS5ZHBh.css.gz → 9.DwS5ZHBh.css.gz} +0 -0
  468. /package/src/{generated/types → lib/types/generated}/API.ts +0 -0
  469. /package/src/{generated/types → lib/types/generated}/APN.ts +0 -0
  470. /package/src/{generated/types → lib/types/generated}/CLI.ts +0 -0
  471. /package/src/{generated/types → lib/types/generated}/Config.ts +0 -0
  472. /package/src/{generated/types → lib/types/generated}/Holder.ts +0 -0
  473. /package/src/{generated/types → lib/types/generated}/JWT.ts +0 -0
  474. /package/src/{generated/types → lib/types/generated}/Notification.ts +0 -0
  475. /package/src/{generated/types → lib/types/generated}/OpenCode.ts +0 -0
  476. /package/src/{generated/types → lib/types/generated}/Sessions.ts +0 -0
  477. /package/src/{generated/types → lib/types/generated}/Terminal.ts +0 -0
  478. /package/src/{generated/types → lib/types/generated}/index.ts +0 -0
@@ -0,0 +1,136 @@
1
+ // Server-side proxy for AI providers that block direct browser requests (CORS).
2
+ // The browser NeuroLink bundle POSTs here; this endpoint forwards to the real API.
3
+ // Currently supports: anthropic (api.anthropic.com blocks browser fetch).
4
+
5
+ import { env } from '$env/dynamic/private';
6
+ import { validateAuth } from '$lib/modules/server/auth';
7
+ import { json } from '@sveltejs/kit';
8
+
9
+ import type { RequestHandler } from './$types';
10
+
11
+ // Per-provider allowlist of client-supplied headers that may be forwarded
12
+ // upstream. Everything else (including host, x-forwarded-*, content-type) is
13
+ // dropped so the browser can't influence provider behavior beyond what we
14
+ // explicitly permit.
15
+ const ALLOWED_CLIENT_HEADERS: Record<string, Set<string>> = {
16
+ anthropic: new Set(['anthropic-beta', 'anthropic-version']),
17
+ 'google-ai': new Set<string>([]),
18
+ mistral: new Set([]),
19
+ openai: new Set(['openai-organization', 'openai-project']),
20
+ };
21
+
22
+ export const POST: RequestHandler = async ({ request }) => {
23
+ const authError = validateAuth(request);
24
+ if (authError) {
25
+ return authError;
26
+ }
27
+
28
+ let payload: unknown;
29
+ try {
30
+ payload = await request.json();
31
+ } catch {
32
+ return json({ error: 'Invalid JSON body' }, { status: 400 });
33
+ }
34
+
35
+ if (
36
+ !payload ||
37
+ typeof payload !== 'object' ||
38
+ typeof (payload as { provider?: unknown }).provider !== 'string' ||
39
+ typeof (payload as { url?: unknown }).url !== 'string' ||
40
+ !(payload as { headers?: unknown }).headers ||
41
+ typeof (payload as { headers?: unknown }).headers !== 'object'
42
+ ) {
43
+ return json({ error: 'Invalid proxy payload' }, { status: 400 });
44
+ }
45
+
46
+ const {
47
+ body,
48
+ headers: reqHeaders,
49
+ provider,
50
+ url,
51
+ } = payload as {
52
+ body: unknown;
53
+ headers: Record<string, string>;
54
+ provider: string;
55
+ url: string;
56
+ };
57
+
58
+ // Only proxy known safe providers — never forward arbitrary URLs
59
+ const ALLOWED_PREFIXES: Record<string, string> = {
60
+ anthropic: 'https://api.anthropic.com/',
61
+ 'google-ai': 'https://generativelanguage.googleapis.com/',
62
+ mistral: 'https://api.mistral.ai/',
63
+ openai: 'https://api.openai.com/',
64
+ };
65
+
66
+ const allowedPrefix = ALLOWED_PREFIXES[provider];
67
+ if (!allowedPrefix || !url.startsWith(allowedPrefix)) {
68
+ return json({ error: `Provider "${provider}" or URL not allowed` }, { status: 403 });
69
+ }
70
+
71
+ // Inject the server-side API key so the browser never sees it
72
+ const apiKeyEnv: Record<string, string> = {
73
+ anthropic: env.ANTHROPIC_API_KEY ?? '',
74
+ 'google-ai': env.GOOGLE_AI_API_KEY ?? '',
75
+ mistral: env.MISTRAL_API_KEY ?? '',
76
+ openai: env.OPENAI_API_KEY ?? '',
77
+ };
78
+
79
+ // Copy only explicitly-allowed headers per provider. Everything else is
80
+ // dropped so the browser can't influence upstream behavior via host,
81
+ // x-forwarded-*, organization selectors, provider feature toggles, etc.
82
+ const allowedForProvider = ALLOWED_CLIENT_HEADERS[provider] ?? new Set<string>();
83
+ const normalizedReqHeaders: Record<string, string> = {};
84
+ for (const [k, v] of Object.entries(reqHeaders)) {
85
+ const key = k.toLowerCase();
86
+ if (allowedForProvider.has(key)) {
87
+ normalizedReqHeaders[key] = v;
88
+ }
89
+ }
90
+
91
+ const forwardHeaders: Record<string, string> = {
92
+ 'Content-Type': 'application/json',
93
+ ...normalizedReqHeaders,
94
+ };
95
+
96
+ // Override / set auth header with server-side key
97
+ if (provider === 'anthropic') {
98
+ forwardHeaders['x-api-key'] = apiKeyEnv.anthropic;
99
+ forwardHeaders['anthropic-version'] = forwardHeaders['anthropic-version'] ?? '2023-06-01';
100
+ } else if (provider === 'google-ai') {
101
+ forwardHeaders['x-goog-api-key'] = apiKeyEnv['google-ai'];
102
+ } else if (provider === 'openai') {
103
+ forwardHeaders.Authorization = `Bearer ${apiKeyEnv.openai}`;
104
+ } else if (provider === 'mistral') {
105
+ forwardHeaders.Authorization = `Bearer ${apiKeyEnv.mistral}`;
106
+ }
107
+
108
+ const controller = new AbortController();
109
+ const timeout = setTimeout(() => {
110
+ controller.abort();
111
+ }, 30_000);
112
+
113
+ let resp: Response;
114
+ try {
115
+ resp = await fetch(url, {
116
+ body: JSON.stringify(body),
117
+ headers: forwardHeaders,
118
+ method: 'POST',
119
+ signal: controller.signal,
120
+ });
121
+ } catch (err) {
122
+ clearTimeout(timeout);
123
+ const message = err instanceof Error ? err.message : 'Upstream request failed';
124
+ return json({ error: message }, { status: 502 });
125
+ }
126
+ clearTimeout(timeout);
127
+
128
+ let data: unknown;
129
+ try {
130
+ data = await resp.json();
131
+ } catch {
132
+ return json({ error: 'Upstream returned non-JSON response' }, { status: 502 });
133
+ }
134
+
135
+ return json(data, { status: resp.status });
136
+ };
@@ -1,4 +1,4 @@
1
- import type { NotificationData } from '$generated/types';
1
+ import type { NotificationData } from '$lib/types';
2
2
 
3
3
  import { env } from '$env/dynamic/private';
4
4
  import { LibraryAPNsService } from '$lib/modules/server/apn/library-apns';
@@ -7,6 +7,7 @@ import { createPendingRequest } from '$lib/modules/server/apn/pending-requests';
7
7
  import { validateAuth } from '$lib/modules/server/auth';
8
8
  import { isFCMConfigured, sendFCMNotification } from '$lib/modules/server/fcm/fcm-service.js';
9
9
  import { toErrorMessage } from '$lib/modules/server/utils/error';
10
+ import { broadcastEvent } from '$lib/modules/server/ws/server';
10
11
  import { json } from '@sveltejs/kit';
11
12
 
12
13
  import type { RequestHandler } from './$types';
@@ -24,15 +25,118 @@ function getAPNsClient(): LibraryAPNsService {
24
25
  const notificationCache = new Map<string, number>();
25
26
  const DEDUP_WINDOW = 10000; // 10 seconds deduplication window
26
27
 
28
+ function broadcastHookEvent(body: Record<string, unknown>): void {
29
+ const data = (body.data ?? {}) as Record<string, unknown>;
30
+ const eventType =
31
+ typeof data.eventType === 'string'
32
+ ? data.eventType
33
+ : typeof body.eventType === 'string'
34
+ ? body.eventType
35
+ : '';
36
+ const tool = typeof data.tool === 'string' ? data.tool : '';
37
+ const terminalId = typeof data.terminalId === 'string' ? data.terminalId : undefined;
38
+ const sessionId = typeof data.sessionId === 'string' ? data.sessionId : undefined;
39
+
40
+ switch (eventType) {
41
+ case 'error':
42
+ broadcastEvent({
43
+ error:
44
+ typeof data.error === 'string'
45
+ ? data.error
46
+ : typeof data.message === 'string'
47
+ ? data.message
48
+ : 'Unknown error',
49
+ terminalId,
50
+ tool,
51
+ type: 'tool-failed',
52
+ });
53
+ break;
54
+ case 'idle_input':
55
+ case 'session.idle':
56
+ broadcastEvent({
57
+ message: typeof data.message === 'string' ? data.message : '',
58
+ sessionId,
59
+ terminalId,
60
+ type: 'agent-idle',
61
+ });
62
+ break;
63
+ case 'permission':
64
+ case 'permission_notification':
65
+ if (data.requestId && data.toolName) {
66
+ broadcastEvent({
67
+ input:
68
+ typeof data.toolInput === 'object' && data.toolInput !== null
69
+ ? (data.toolInput as Record<string, unknown>)
70
+ : {},
71
+ requestId: data.requestId as string,
72
+ tool: data.toolName as string,
73
+ type: 'permission-requested',
74
+ });
75
+ }
76
+ break;
77
+ case 'question':
78
+ broadcastEvent({
79
+ message: typeof data.message === 'string' ? data.message : '',
80
+ sessionId,
81
+ terminalId,
82
+ type: 'agent-question',
83
+ });
84
+ break;
85
+ case 'tool.after':
86
+ broadcastEvent({ success: true, terminalId, tool, type: 'tool-completed' });
87
+ break;
88
+ case 'tool.before':
89
+ broadcastEvent({
90
+ command: typeof data.command === 'string' ? data.command : '',
91
+ filePath:
92
+ typeof data.filePath === 'string'
93
+ ? data.filePath
94
+ : typeof data.files === 'string'
95
+ ? data.files
96
+ : '',
97
+ terminalId,
98
+ tool,
99
+ type: 'tool-started',
100
+ });
101
+ break;
102
+ // session.status, intervention — skip or use existing types
103
+ }
104
+ }
105
+
106
+ /** Build a notification history record from common fields. */
107
+ function buildNotificationRecord(
108
+ id: string,
109
+ title: string,
110
+ message: string,
111
+ status: 'failed' | 'filtered' | 'sent' | 'skipped',
112
+ data?: NotificationData,
113
+ error?: null | string
114
+ ): Parameters<typeof addNotification>[0] {
115
+ return {
116
+ category: data?.category ?? null,
117
+ data: (data as Record<string, unknown>) ?? null,
118
+ error: error ?? null,
119
+ id,
120
+ message,
121
+ project: data?.project ?? null,
122
+ source: data?.source ?? null,
123
+ status,
124
+ timestamp: new Date().toISOString(),
125
+ title,
126
+ tool: data?.tool ?? null,
127
+ };
128
+ }
129
+
27
130
  function intelligentNotificationFilter(
28
131
  title: string,
29
132
  message: string,
30
- data?: NotificationData
133
+ data?: NotificationData,
134
+ waitForResponse = false
31
135
  ): { reason: string; send: boolean } {
32
136
  const source = data?.source || 'unknown';
33
137
 
34
138
  // Check for duplicate notifications first
35
- if (isDuplicateNotification(title, message, data)) {
139
+ if (isDuplicateNotification(title, message, data, waitForResponse)) {
36
140
  return {
37
141
  reason: 'Duplicate notification within 10-second window',
38
142
  send: false,
@@ -100,12 +204,23 @@ function intelligentNotificationFilter(
100
204
  };
101
205
  }
102
206
 
103
- function isDuplicateNotification(title: string, message: string, data?: NotificationData): boolean {
207
+ function isDuplicateNotification(
208
+ title: string,
209
+ message: string,
210
+ data?: NotificationData,
211
+ waitForResponse = false
212
+ ): boolean {
213
+ // Never deduplicate bidirectional permission requests — each one creates a
214
+ // unique pending request that the hook polls by requestId.
215
+ if (waitForResponse) {
216
+ return false;
217
+ }
218
+
104
219
  const key = `${title}|${message}|${data?.category || 'unknown'}`;
105
220
  const now = Date.now();
106
221
 
107
222
  if (notificationCache.has(key)) {
108
- const lastSent = notificationCache.get(key)!;
223
+ const lastSent = notificationCache.get(key) ?? 0;
109
224
  if (now - lastSent < DEDUP_WINDOW) {
110
225
  return true; // Duplicate within time window
111
226
  }
@@ -159,6 +274,13 @@ export const POST: RequestHandler = async ({ request }) => {
159
274
  const waitForResponse =
160
275
  typeof body.waitForResponse === 'boolean' ? body.waitForResponse : false;
161
276
 
277
+ // Broadcast to /ws/events for real-time activity feed
278
+ try {
279
+ broadcastHookEvent(body);
280
+ } catch {
281
+ // Best-effort broadcast — don't fail the notify request
282
+ }
283
+
162
284
  if (!title || typeof title !== 'string' || !message || typeof message !== 'string') {
163
285
  return json({ error: 'Title and message are required and must be strings' }, { status: 400 });
164
286
  }
@@ -171,22 +293,24 @@ export const POST: RequestHandler = async ({ request }) => {
171
293
  const requestId = Math.random().toString(36).substring(2, 15);
172
294
  const dataRequestId = typeof data?.requestId === 'string' ? data.requestId : undefined;
173
295
  const canonicalRequestId = dataRequestId || requestId;
174
- const shouldSendNotification = intelligentNotificationFilter(title, message, data);
296
+ const shouldSendNotification = intelligentNotificationFilter(
297
+ title,
298
+ message,
299
+ data,
300
+ waitForResponse
301
+ );
175
302
 
176
303
  if (!shouldSendNotification.send) {
177
- addNotification({
178
- category: data?.category ?? null,
179
- data: (data as Record<string, unknown>) ?? null,
180
- error: shouldSendNotification.reason,
181
- id: canonicalRequestId,
182
- message,
183
- project: data?.project ?? null,
184
- source: data?.source ?? null,
185
- status: 'filtered',
186
- timestamp: new Date().toISOString(),
187
- title,
188
- tool: data?.tool ?? null,
189
- });
304
+ addNotification(
305
+ buildNotificationRecord(
306
+ canonicalRequestId,
307
+ title,
308
+ message,
309
+ 'filtered',
310
+ data,
311
+ shouldSendNotification.reason
312
+ )
313
+ );
190
314
 
191
315
  return json({
192
316
  message: 'Notification filtered (not sent)',
@@ -209,19 +333,7 @@ export const POST: RequestHandler = async ({ request }) => {
209
333
  });
210
334
  }
211
335
 
212
- addNotification({
213
- category: data?.category ?? null,
214
- data: (data as Record<string, unknown>) ?? null,
215
- error: null,
216
- id: canonicalRequestId,
217
- message,
218
- project: data?.project ?? null,
219
- source: data?.source ?? null,
220
- status: 'skipped',
221
- timestamp: new Date().toISOString(),
222
- title,
223
- tool: data?.tool ?? null,
224
- });
336
+ addNotification(buildNotificationRecord(canonicalRequestId, title, message, 'skipped', data));
225
337
 
226
338
  return json({
227
339
  message: 'Push skipped (WebSocket clients connected)',
@@ -293,19 +405,7 @@ export const POST: RequestHandler = async ({ request }) => {
293
405
  });
294
406
  }
295
407
 
296
- addNotification({
297
- category: data?.category ?? null,
298
- data: (data as Record<string, unknown>) ?? null,
299
- error: null,
300
- id: canonicalRequestId,
301
- message,
302
- project: data?.project ?? null,
303
- source: data?.source ?? null,
304
- status: 'sent',
305
- timestamp: new Date().toISOString(),
306
- title,
307
- tool: data?.tool ?? null,
308
- });
408
+ addNotification(buildNotificationRecord(canonicalRequestId, title, message, 'sent', data));
309
409
 
310
410
  return json({
311
411
  message: 'Notification sent successfully',
@@ -317,19 +417,16 @@ export const POST: RequestHandler = async ({ request }) => {
317
417
  } else {
318
418
  console.error(`[notify] FCM delivery failed: ${fcmResult.error}`);
319
419
 
320
- addNotification({
321
- category: data?.category ?? null,
322
- data: (data as Record<string, unknown>) ?? null,
323
- error: fcmResult.error ?? null,
324
- id: canonicalRequestId,
325
- message,
326
- project: data?.project ?? null,
327
- source: data?.source ?? null,
328
- status: 'failed',
329
- timestamp: new Date().toISOString(),
330
- title,
331
- tool: data?.tool ?? null,
332
- });
420
+ addNotification(
421
+ buildNotificationRecord(
422
+ canonicalRequestId,
423
+ title,
424
+ message,
425
+ 'failed',
426
+ data,
427
+ fcmResult.error
428
+ )
429
+ );
333
430
 
334
431
  return json(
335
432
  {
@@ -384,19 +481,7 @@ export const POST: RequestHandler = async ({ request }) => {
384
481
  });
385
482
  }
386
483
 
387
- addNotification({
388
- category: data?.category ?? null,
389
- data: (data as Record<string, unknown>) ?? null,
390
- error: null,
391
- id: canonicalRequestId,
392
- message,
393
- project: data?.project ?? null,
394
- source: data?.source ?? null,
395
- status: 'sent',
396
- timestamp: new Date().toISOString(),
397
- title,
398
- tool: data?.tool ?? null,
399
- });
484
+ addNotification(buildNotificationRecord(canonicalRequestId, title, message, 'sent', data));
400
485
 
401
486
  return json({
402
487
  message: 'Notification sent successfully',
@@ -409,19 +494,9 @@ export const POST: RequestHandler = async ({ request }) => {
409
494
  const notifErrMsg = toErrorMessage(notificationError);
410
495
  console.error(`[notify] APNs delivery failed: ${notifErrMsg}`);
411
496
 
412
- addNotification({
413
- category: data?.category ?? null,
414
- data: (data as Record<string, unknown>) ?? null,
415
- error: notifErrMsg,
416
- id: canonicalRequestId,
417
- message,
418
- project: data?.project ?? null,
419
- source: data?.source ?? null,
420
- status: 'failed',
421
- timestamp: new Date().toISOString(),
422
- title,
423
- tool: data?.tool ?? null,
424
- });
497
+ addNotification(
498
+ buildNotificationRecord(canonicalRequestId, title, message, 'failed', data, notifErrMsg)
499
+ );
425
500
 
426
501
  return json(
427
502
  {
@@ -1,4 +1,4 @@
1
- import type { ProjectGroup } from '$lib/modules/server/sessions/types';
1
+ import type { ProjectGroup } from '$lib/types';
2
2
 
3
3
  import { validateAuth } from '$lib/modules/server/auth';
4
4
  import {
@@ -65,9 +65,11 @@ export const POST: RequestHandler = async ({ request }) => {
65
65
 
66
66
  const existing = ptyManager
67
67
  .list()
68
- .find((t) => t.status === 'running' && (
69
- t.sessionFile?.endsWith(`/${sessionId}.jsonl`) || t.openCodeSessionId === sessionId
70
- ));
68
+ .find(
69
+ (t) =>
70
+ t.status === 'running' &&
71
+ (t.sessionFile?.endsWith(`/${sessionId}.jsonl`) || t.openCodeSessionId === sessionId)
72
+ );
71
73
 
72
74
  if (existing) {
73
75
  console.log(
@@ -94,8 +96,7 @@ export const POST: RequestHandler = async ({ request }) => {
94
96
 
95
97
  // --- Build args based on command ---
96
98
 
97
- const args: string[] =
98
- command === 'claude' ? ['--resume', sessionId] : ['--session', sessionId];
99
+ const args: string[] = command === 'claude' ? ['--resume', sessionId] : ['--session', sessionId];
99
100
 
100
101
  try {
101
102
  const terminal = await ptyManager.create(command, args, realCwd, 120, 40);
@@ -107,7 +108,10 @@ export const POST: RequestHandler = async ({ request }) => {
107
108
  return json(
108
109
  {
109
110
  command: terminal.command,
110
- createdAt: terminal.createdAt instanceof Date ? terminal.createdAt.toISOString() : terminal.createdAt,
111
+ createdAt:
112
+ terminal.createdAt instanceof Date
113
+ ? terminal.createdAt.toISOString()
114
+ : terminal.createdAt,
111
115
  cwd: terminal.cwd,
112
116
  id: terminal.id,
113
117
  pid: terminal.pid,
@@ -9,6 +9,21 @@ import type { RequestHandler } from './$types';
9
9
 
10
10
  const ALLOWED_COMMANDS = ['zsh', 'bash', 'sh', 'fish', 'claude', 'opencode'];
11
11
 
12
+ /** Extract the last non-empty line from a scrollback string. */
13
+ function lastScrollbackLine(scrollback: string): null | string {
14
+ if (!scrollback) {
15
+ return null;
16
+ }
17
+ const lines = scrollback.trimEnd().split('\n');
18
+ for (let i = lines.length - 1; i >= 0; i--) {
19
+ const line = lines[i].trim();
20
+ if (line) {
21
+ return line.slice(0, 200);
22
+ }
23
+ }
24
+ return null;
25
+ }
26
+
12
27
  // GET /api/terminals — List all terminals (active + recently exited)
13
28
  export const GET: RequestHandler = ({ request }) => {
14
29
  const authError = validateAuth(request);
@@ -28,6 +43,7 @@ export const GET: RequestHandler = ({ request }) => {
28
43
  exitedAt: t.exitedAt?.toISOString() ?? null,
29
44
  id: t.id,
30
45
  isActive: t.isActive,
46
+ lastOutput: lastScrollbackLine(t.scrollback),
31
47
  pid: t.pid,
32
48
  status: t.status,
33
49
  }));
@@ -127,7 +143,10 @@ export const POST: RequestHandler = async ({ request }) => {
127
143
  return json(
128
144
  {
129
145
  command: terminal.command,
130
- createdAt: terminal.createdAt instanceof Date ? terminal.createdAt.toISOString() : terminal.createdAt,
146
+ createdAt:
147
+ terminal.createdAt instanceof Date
148
+ ? terminal.createdAt.toISOString()
149
+ : terminal.createdAt,
131
150
  cwd: terminal.cwd,
132
151
  id: terminal.id,
133
152
  pid: terminal.pid,
@@ -5,6 +5,21 @@ import { json } from '@sveltejs/kit';
5
5
 
6
6
  import type { RequestHandler } from './$types';
7
7
 
8
+ /** Extract the last non-empty line from a scrollback string. */
9
+ function lastScrollbackLine(scrollback: string): null | string {
10
+ if (!scrollback) {
11
+ return null;
12
+ }
13
+ const lines = scrollback.trimEnd().split('\n');
14
+ for (let i = lines.length - 1; i >= 0; i--) {
15
+ const line = lines[i].trim();
16
+ if (line) {
17
+ return line.slice(0, 200);
18
+ }
19
+ }
20
+ return null;
21
+ }
22
+
8
23
  // GET /api/terminals/:id — Get terminal details by ID
9
24
  export const GET: RequestHandler = ({ params, request }) => {
10
25
  const authError = validateAuth(request);
@@ -28,8 +43,7 @@ export const GET: RequestHandler = ({ params, request }) => {
28
43
  exitCode: terminal.exitCode,
29
44
  exitedAt: terminal.exitedAt?.toISOString() ?? null,
30
45
  id: terminal.id,
31
- lastOutput:
32
- terminal.scrollback.length > 0 ? terminal.scrollback[terminal.scrollback.length - 1] : null,
46
+ lastOutput: lastScrollbackLine(terminal.scrollback),
33
47
  pid: terminal.pid,
34
48
  sessionWs: `/ws/session/${terminal.id}`,
35
49
  status: terminal.status,
@@ -1,40 +1,12 @@
1
1
  import { validateAuth } from '$lib/modules/server/auth';
2
- import { toErrorMessage } from '$lib/modules/server/utils/error';
3
2
  import { json } from '@sveltejs/kit';
4
3
 
5
4
  import type { RequestHandler } from './$types';
6
5
 
7
- // TODO: Add HMAC signature validation for webhook payloads.
8
- // This is currently a stub endpoint — no signature verification is performed.
9
- export const POST: RequestHandler = async ({ request }) => {
10
- try {
11
- const authError = validateAuth(request);
12
- if (authError) {
13
- return authError;
14
- }
15
-
16
- const body = (await request.json()) as Record<string, unknown>;
17
-
18
- console.log('Webhook received:', {
19
- body,
20
- timestamp: new Date().toISOString(),
21
- });
22
-
23
- // In a full implementation, this would forward to Claude Code
24
- // For now, just log and acknowledge
25
-
26
- return json({
27
- message: 'Webhook received successfully',
28
- success: true,
29
- timestamp: new Date().toISOString(),
30
- });
31
- } catch (error) {
32
- console.error('[webhook] Failed to process webhook:', toErrorMessage(error));
33
- return json(
34
- {
35
- error: 'Failed to process webhook',
36
- },
37
- { status: 500 }
38
- );
6
+ export const POST: RequestHandler = ({ request }) => {
7
+ const authError = validateAuth(request);
8
+ if (authError) {
9
+ return authError;
39
10
  }
11
+ return json({ error: 'Webhook endpoint not implemented' }, { status: 501 });
40
12
  };
@@ -5,7 +5,7 @@
5
5
  // query parameter on the WebSocket upgrade URL, keeping the long-lived API_KEY
6
6
  // out of URL strings (which appear in proxy logs and browser history).
7
7
  //
8
- // Rate limited to 10 requests per minute per API key.
8
+ // Rate limited to 30 requests per minute per API key.
9
9
 
10
10
  import { validateAuth } from '$lib/modules/server/auth';
11
11
  import { generateTicket } from '$lib/modules/server/ws/ticket-store';
@@ -16,7 +16,7 @@ import type { RequestHandler } from './$types';
16
16
  // ── Rate limiting ───────────────────────────────────────────────────
17
17
 
18
18
  const RATE_LIMIT_WINDOW_MS = 60_000; // 60 seconds
19
- const RATE_LIMIT_MAX = 10; // max 10 requests per window
19
+ const RATE_LIMIT_MAX = 30; // max 30 requests per window (activity feed + dashboard + per-terminal sockets)
20
20
 
21
21
  /** Maps API key -> array of request timestamps (epoch ms). */
22
22
  const rateLimitMap = new Map<string, number[]>();
@@ -69,11 +69,11 @@ export const POST: RequestHandler = ({ request }) => {
69
69
  }
70
70
 
71
71
  // Extract the API key for rate limiting
72
- const apiKey = request.headers.get('authorization')!.substring(7);
72
+ const apiKey = (request.headers.get('authorization') ?? '').substring(7).trim();
73
73
 
74
74
  if (!checkRateLimit(apiKey)) {
75
75
  return json(
76
- { error: 'Rate limit exceeded. Maximum 10 ticket requests per minute.' },
76
+ { error: 'Rate limit exceeded. Maximum 30 ticket requests per minute.' },
77
77
  { status: 429 }
78
78
  );
79
79
  }
@@ -0,0 +1,9 @@
1
+ import { env } from '$env/dynamic/private';
2
+ import { getProviderAvailability } from '$lib/modules/shared/providers';
3
+
4
+ import type { PageServerLoad } from './$types';
5
+
6
+ export const load: PageServerLoad = () => ({
7
+ activeProvider: env.NEUROLINK_PROVIDER ?? '',
8
+ aiProviders: getProviderAvailability(env),
9
+ });