@juspay/shooter 1.5.0 → 1.6.1

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/CsgHjHGZ.js +1 -0
  49. package/build/client/_app/immutable/chunks/CsgHjHGZ.js.br +0 -0
  50. package/build/client/_app/immutable/chunks/CsgHjHGZ.js.gz +0 -0
  51. package/build/client/_app/immutable/chunks/{UJOiqIYE.js → CtrCjGZT.js} +1 -1
  52. package/build/client/_app/immutable/chunks/CtrCjGZT.js.br +0 -0
  53. package/build/client/_app/immutable/chunks/CtrCjGZT.js.gz +0 -0
  54. package/build/client/_app/immutable/chunks/DDiOVAd8.js +61 -0
  55. package/build/client/_app/immutable/chunks/DDiOVAd8.js.br +0 -0
  56. package/build/client/_app/immutable/chunks/DDiOVAd8.js.gz +0 -0
  57. package/build/client/_app/immutable/chunks/DVl0sebP.js +2 -0
  58. package/build/client/_app/immutable/chunks/DVl0sebP.js.br +0 -0
  59. package/build/client/_app/immutable/chunks/DVl0sebP.js.gz +0 -0
  60. package/build/client/_app/immutable/chunks/{CiF38mQq.js → Dc_Gg2H6.js} +1 -1
  61. package/build/client/_app/immutable/chunks/Dc_Gg2H6.js.br +0 -0
  62. package/build/client/_app/immutable/chunks/Dc_Gg2H6.js.gz +0 -0
  63. package/build/client/_app/immutable/chunks/{CRbaG9cv.js → DlnAjkg1.js} +1 -1
  64. package/build/client/_app/immutable/chunks/DlnAjkg1.js.br +0 -0
  65. package/build/client/_app/immutable/chunks/{CRbaG9cv.js.gz → DlnAjkg1.js.gz} +0 -0
  66. package/build/client/_app/immutable/chunks/YKoRJzXZ.js +3 -0
  67. package/build/client/_app/immutable/chunks/YKoRJzXZ.js.br +0 -0
  68. package/build/client/_app/immutable/chunks/YKoRJzXZ.js.gz +0 -0
  69. package/build/client/_app/immutable/chunks/gQJcRhou.js +1 -0
  70. package/build/client/_app/immutable/chunks/gQJcRhou.js.br +0 -0
  71. package/build/client/_app/immutable/chunks/gQJcRhou.js.gz +0 -0
  72. package/build/client/_app/immutable/chunks/pRcLbE0d.js +1 -0
  73. package/build/client/_app/immutable/chunks/pRcLbE0d.js.br +0 -0
  74. package/build/client/_app/immutable/chunks/pRcLbE0d.js.gz +0 -0
  75. package/build/client/_app/immutable/entry/app.CFPgQOa8.js +2 -0
  76. package/build/client/_app/immutable/entry/app.CFPgQOa8.js.br +0 -0
  77. package/build/client/_app/immutable/entry/app.CFPgQOa8.js.gz +0 -0
  78. package/build/client/_app/immutable/entry/start.BnJOVqhI.js +1 -0
  79. package/build/client/_app/immutable/entry/start.BnJOVqhI.js.br +2 -0
  80. package/build/client/_app/immutable/entry/start.BnJOVqhI.js.gz +0 -0
  81. package/build/client/_app/immutable/nodes/0.DR-BBF5r.js +1 -0
  82. package/build/client/_app/immutable/nodes/0.DR-BBF5r.js.br +0 -0
  83. package/build/client/_app/immutable/nodes/0.DR-BBF5r.js.gz +0 -0
  84. package/build/client/_app/immutable/nodes/1.CNm6rAwf.js +1 -0
  85. package/build/client/_app/immutable/nodes/1.CNm6rAwf.js.br +0 -0
  86. package/build/client/_app/immutable/nodes/1.CNm6rAwf.js.gz +0 -0
  87. package/build/client/_app/immutable/nodes/2.B08usYzr.js +13 -0
  88. package/build/client/_app/immutable/nodes/2.B08usYzr.js.br +0 -0
  89. package/build/client/_app/immutable/nodes/2.B08usYzr.js.gz +0 -0
  90. package/build/client/_app/immutable/nodes/3.CsY6J5HS.js +9 -0
  91. package/build/client/_app/immutable/nodes/3.CsY6J5HS.js.br +0 -0
  92. package/build/client/_app/immutable/nodes/3.CsY6J5HS.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.CbQQ3FtZ.js +1 -0
  100. package/build/client/_app/immutable/nodes/6.CbQQ3FtZ.js.br +0 -0
  101. package/build/client/_app/immutable/nodes/6.CbQQ3FtZ.js.gz +0 -0
  102. package/build/client/_app/immutable/nodes/{5.DIkXVP4q.js → 7.CCKgiNNk.js} +3 -3
  103. package/build/client/_app/immutable/nodes/7.CCKgiNNk.js.br +0 -0
  104. package/build/client/_app/immutable/nodes/7.CCKgiNNk.js.gz +0 -0
  105. package/build/client/_app/immutable/nodes/8.C7AaheUD.js +2 -0
  106. package/build/client/_app/immutable/nodes/8.C7AaheUD.js.br +0 -0
  107. package/build/client/_app/immutable/nodes/8.C7AaheUD.js.gz +0 -0
  108. package/build/client/_app/immutable/nodes/9.DfL9kMC4.js +2 -0
  109. package/build/client/_app/immutable/nodes/9.DfL9kMC4.js.br +0 -0
  110. package/build/client/_app/immutable/nodes/9.DfL9kMC4.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-DC2VLooL.js +23 -0
  115. package/build/server/chunks/0-DC2VLooL.js.map +1 -0
  116. package/build/server/chunks/1-XJaf8Jvf.js +9 -0
  117. package/build/server/chunks/{1-D0N7vVhH.js.map → 1-XJaf8Jvf.js.map} +1 -1
  118. package/build/server/chunks/2-D4Cx-1QL.js +21 -0
  119. package/build/server/chunks/2-D4Cx-1QL.js.map +1 -0
  120. package/build/server/chunks/3-CVhIEP-u.js +21 -0
  121. package/build/server/chunks/3-CVhIEP-u.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-QFSbzRMP.js +9 -0
  127. package/build/server/chunks/6-QFSbzRMP.js.map +1 -0
  128. package/build/server/chunks/7-CZ_YGjMV.js +9 -0
  129. package/build/server/chunks/7-CZ_YGjMV.js.map +1 -0
  130. package/build/server/chunks/8-Xe2Rugb4.js +9 -0
  131. package/build/server/chunks/8-Xe2Rugb4.js.map +1 -0
  132. package/build/server/chunks/9-IwHpC4SO.js +9 -0
  133. package/build/server/chunks/9-IwHpC4SO.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-tSpgyl1D.js → _server.ts-Bjbr7glm.js} +4 -3
  175. package/build/server/chunks/_server.ts-Bjbr7glm.js.map +1 -0
  176. package/build/server/chunks/{_server.ts-COu0vNpd.js → _server.ts-BrqaMMAa.js} +7 -6
  177. package/build/server/chunks/_server.ts-BrqaMMAa.js.map +1 -0
  178. package/build/server/chunks/{_server.ts-vekTmWAx.js → _server.ts-BuYyCrnF.js} +6 -4
  179. package/build/server/chunks/_server.ts-BuYyCrnF.js.map +1 -0
  180. package/build/server/chunks/{_server.ts-DYvb9ijZ.js → _server.ts-ByPExYfO.js} +4 -3
  181. package/build/server/chunks/{_server.ts-DYvb9ijZ.js.map → _server.ts-ByPExYfO.js.map} +1 -1
  182. package/build/server/chunks/_server.ts-CjpQ10xh.js +123 -0
  183. package/build/server/chunks/_server.ts-CjpQ10xh.js.map +1 -0
  184. package/build/server/chunks/_server.ts-CyjDrcZN.js +21 -0
  185. package/build/server/chunks/_server.ts-CyjDrcZN.js.map +1 -0
  186. package/build/server/chunks/{_server.ts-DV8zTCF9.js → _server.ts-DOGUMzPx.js} +4 -3
  187. package/build/server/chunks/{_server.ts-DV8zTCF9.js.map → _server.ts-DOGUMzPx.js.map} +1 -1
  188. package/build/server/chunks/_server.ts-DZvfyuNj.js +15 -0
  189. package/build/server/chunks/_server.ts-DZvfyuNj.js.map +1 -0
  190. package/build/server/chunks/{_server.ts-XzT2UHM1.js → _server.ts-DkPPTUPo.js} +4 -3
  191. package/build/server/chunks/{_server.ts-XzT2UHM1.js.map → _server.ts-DkPPTUPo.js.map} +1 -1
  192. package/build/server/chunks/{_server.ts-Deok2y88.js → _server.ts-Ds_SUGC3.js} +184 -90
  193. package/build/server/chunks/_server.ts-Ds_SUGC3.js.map +1 -0
  194. package/build/server/chunks/{_server.ts-Ch-6iOHp.js → _server.ts-G8OeADGj.js} +141 -89
  195. package/build/server/chunks/_server.ts-G8OeADGj.js.map +1 -0
  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 +144 -76
  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 +190 -87
  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,478 @@
1
+ // Activity feed store — session-based polling and WebSocket streaming.
2
+ // Polls for active sessions, connects to each session's WebSocket, buffers events,
3
+ // and triggers AI summarization.
4
+
5
+ import type {
6
+ ActivityEvent,
7
+ ActivitySessionMessage,
8
+ ActivitySessionRecord,
9
+ ActivitySummary,
10
+ } from '$lib/types';
11
+
12
+ import { getApiKey } from '$lib/modules/client/common';
13
+ import { SvelteMap } from 'svelte/reactivity';
14
+
15
+ import { summarizeEvents } from './summarizer';
16
+
17
+ // -- Constants ------------------------------------------------------------
18
+
19
+ const MAX_EVENTS = 200;
20
+ const MAX_SUMMARIES = 50;
21
+ const SUMMARY_BATCH_SIZE = 5;
22
+ const SUMMARY_INTERVAL_MS = 15_000;
23
+ const POLL_INTERVAL_MS = 15_000;
24
+ const ACTIVE_THRESHOLD_MINUTES = 5;
25
+
26
+ // -- State (Svelte 5 runes) -----------------------------------------------
27
+
28
+ let events = $state<ActivityEvent[]>([]);
29
+ let summaries = $state<ActivitySummary[]>([]);
30
+ let aiAvailable = $state(true);
31
+ let connected = $state(false);
32
+ let summarizing = $state(false);
33
+
34
+ let pollTimer: null | ReturnType<typeof setInterval> = null;
35
+ let summaryTimer: null | ReturnType<typeof setInterval> = null;
36
+ let counter = 0;
37
+
38
+ // Per-session WebSocket connections
39
+ const sessionSockets = new SvelteMap<string, WebSocket>();
40
+
41
+ // Stored API key for polling
42
+ let storedApiKey = '';
43
+ let storedTicketFetcher: (() => Promise<string>) | null = null;
44
+
45
+ // -- Public API -----------------------------------------------------------
46
+
47
+ export async function connect(ticketFetcher: () => Promise<string>): Promise<void> {
48
+ if (pollTimer) {
49
+ // Already connected
50
+ return;
51
+ }
52
+
53
+ storedApiKey = getApiKey();
54
+ if (!storedApiKey) {
55
+ console.warn('[ActivityStore] No API key available');
56
+ return;
57
+ }
58
+
59
+ storedTicketFetcher = ticketFetcher;
60
+
61
+ // Initial session discovery
62
+ await discoverAndConnectSessions();
63
+
64
+ // Start polling for new sessions every 15s
65
+ pollTimer = setInterval(() => {
66
+ void discoverAndConnectSessions();
67
+ }, POLL_INTERVAL_MS);
68
+
69
+ // Start periodic summarization
70
+ summaryTimer = setInterval(() => {
71
+ void tryGenerateSummary();
72
+ }, SUMMARY_INTERVAL_MS);
73
+ }
74
+
75
+ export function disconnect(): void {
76
+ if (pollTimer) {
77
+ clearInterval(pollTimer);
78
+ pollTimer = null;
79
+ }
80
+
81
+ if (summaryTimer) {
82
+ clearInterval(summaryTimer);
83
+ summaryTimer = null;
84
+ }
85
+
86
+ // Close all session sockets
87
+ for (const [sessionId, sock] of sessionSockets) {
88
+ sock.onclose = null;
89
+ sock.close();
90
+ console.log(`[ActivityStore] Closed session socket for ${sessionId}`);
91
+ }
92
+ sessionSockets.clear();
93
+
94
+ // Reset in-memory feed so reconnect starts clean (no duplicate history replay
95
+ // or stale summary/banner state carried forward).
96
+ events = [];
97
+ summaries = [];
98
+ counter = 0;
99
+ aiAvailable = true;
100
+ summarizing = false;
101
+ connected = false;
102
+ storedApiKey = '';
103
+ storedTicketFetcher = null;
104
+ }
105
+
106
+ export function getEvents(): ActivityEvent[] {
107
+ return events;
108
+ }
109
+
110
+ export function getSummaries(): ActivitySummary[] {
111
+ return summaries;
112
+ }
113
+
114
+ export function isAiAvailable(): boolean {
115
+ return aiAvailable;
116
+ }
117
+
118
+ export function isConnected(): boolean {
119
+ return connected;
120
+ }
121
+
122
+ export function isSummarizing(): boolean {
123
+ return summarizing;
124
+ }
125
+
126
+ // -- Internal: Session Discovery ------------------------------------------
127
+
128
+ /** Add a typed event to the activity buffer. */
129
+ function addActivityEvent(
130
+ session: ActivitySessionRecord,
131
+ eventType: string,
132
+ eventData: Record<string, unknown>,
133
+ timestamp?: string
134
+ ): void {
135
+ const event: ActivityEvent = {
136
+ data: eventData,
137
+ id: `evt-${++counter}`,
138
+ projectName: session.projectName,
139
+ sessionId: session.id,
140
+ summarized: false,
141
+ timestamp: timestamp || new Date().toISOString(),
142
+ type: eventType,
143
+ };
144
+
145
+ events = [...events, event].slice(-MAX_EVENTS);
146
+
147
+ // Trigger summary when batch size reached
148
+ const pending = events.filter((e) => !e.summarized);
149
+ if (pending.length >= SUMMARY_BATCH_SIZE) {
150
+ void tryGenerateSummary();
151
+ }
152
+ }
153
+
154
+ async function connectSessionSocket(session: ActivitySessionRecord): Promise<void> {
155
+ if (!storedTicketFetcher) {
156
+ return;
157
+ }
158
+
159
+ try {
160
+ const ticket = await storedTicketFetcher();
161
+ const wsBase = window.location.origin.replace(/^http/, 'ws');
162
+ const wsUrl = `${wsBase}/ws/session/${session.id}?ticket=${ticket}`;
163
+
164
+ console.log(`[ActivityStore] Connecting to session ${session.id}`);
165
+ const sock = new WebSocket(wsUrl);
166
+ sessionSockets.set(session.id, sock);
167
+
168
+ sock.onopen = (): void => {
169
+ console.log(`[ActivityStore] Session socket opened: ${session.id}`);
170
+ connected = true;
171
+ };
172
+
173
+ sock.onmessage = (msg: MessageEvent): void => {
174
+ try {
175
+ const raw: unknown = JSON.parse(msg.data as string);
176
+ if (!raw || typeof raw !== 'object') {
177
+ return;
178
+ }
179
+
180
+ const data = raw as Record<string, unknown>;
181
+ handleActivitySessionMessage(session, data);
182
+
183
+ // Trigger immediate summary after receiving history batch
184
+ if (data.type === 'history') {
185
+ void tryGenerateSummary();
186
+ }
187
+ } catch {
188
+ // ignore malformed
189
+ }
190
+ };
191
+
192
+ sock.onclose = (): void => {
193
+ console.log(`[ActivityStore] Session socket closed: ${session.id}`);
194
+ sessionSockets.delete(session.id);
195
+ connected = sessionSockets.size > 0;
196
+ };
197
+
198
+ sock.onerror = (err: Event): void => {
199
+ console.warn(`[ActivityStore] Session socket error for ${session.id}:`, err);
200
+ sessionSockets.delete(session.id);
201
+ connected = sessionSockets.size > 0;
202
+ };
203
+ } catch (err) {
204
+ console.warn(`[ActivityStore] Failed to connect session ${session.id}:`, err);
205
+ }
206
+ }
207
+
208
+ async function discoverAndConnectSessions(): Promise<void> {
209
+ if (!storedApiKey) {
210
+ return;
211
+ }
212
+
213
+ try {
214
+ const res = await fetch('/api/sessions?limit=50', {
215
+ headers: { Authorization: `Bearer ${storedApiKey}` },
216
+ });
217
+
218
+ if (!res.ok) {
219
+ console.warn('[ActivityStore] Failed to fetch sessions:', res.status);
220
+ return;
221
+ }
222
+
223
+ const body = (await res.json()) as {
224
+ projects?: {
225
+ fullPath: string;
226
+ id: string;
227
+ lastModified: string;
228
+ name: string;
229
+ sessions: {
230
+ created: string;
231
+ id: string;
232
+ messageCount: number;
233
+ modified: string;
234
+ title: string;
235
+ }[];
236
+ }[];
237
+ };
238
+ const projects = body.projects ?? [];
239
+
240
+ // Flatten projects into session records, filter to sessions modified in last 5 minutes
241
+ const cutoff = Date.now() - ACTIVE_THRESHOLD_MINUTES * 60 * 1000;
242
+ const activeSessions: ActivitySessionRecord[] = [];
243
+ for (const project of projects) {
244
+ for (const session of project.sessions) {
245
+ const modified = Date.parse(session.modified);
246
+ if (modified > cutoff) {
247
+ activeSessions.push({
248
+ createdAt: session.created,
249
+ id: session.id,
250
+ modifiedAt: session.modified,
251
+ projectName: project.name,
252
+ projectPath: project.fullPath,
253
+ });
254
+ }
255
+ }
256
+ }
257
+
258
+ const activeIds = new Set(activeSessions.map((s) => s.id));
259
+
260
+ // Close sockets for sessions that are no longer active
261
+ for (const [sessionId, sock] of sessionSockets) {
262
+ if (!activeIds.has(sessionId)) {
263
+ sock.onclose = null;
264
+ sock.close();
265
+ sessionSockets.delete(sessionId);
266
+ console.log(`[ActivityStore] Session ${sessionId} went stale, closed socket`);
267
+ }
268
+ }
269
+
270
+ // Open sockets for new active sessions
271
+ for (const session of activeSessions) {
272
+ if (!sessionSockets.has(session.id)) {
273
+ void connectSessionSocket(session);
274
+ }
275
+ }
276
+
277
+ connected = sessionSockets.size > 0;
278
+ } catch (err) {
279
+ console.warn('[ActivityStore] Error discovering sessions:', err);
280
+ }
281
+ }
282
+
283
+ function handleActivitySessionMessage(
284
+ session: ActivitySessionRecord,
285
+ data: Record<string, unknown>
286
+ ): void {
287
+ const type = data.type as string | undefined;
288
+
289
+ if (type === 'history' && Array.isArray(data.messages)) {
290
+ // Initial batch — process last 20 for context
291
+ const messages = data.messages as ActivitySessionMessage[];
292
+ const recentMessages = messages.slice(-20);
293
+ for (const msg of recentMessages) {
294
+ processMessage(session, msg);
295
+ }
296
+ } else if (type === 'message') {
297
+ // Conversation message (role + content)
298
+ processMessage(session, {
299
+ content: (data.content as ActivitySessionMessage['content']) || '',
300
+ role: (data.role as string) || 'assistant',
301
+ timestamp: data.timestamp as string,
302
+ });
303
+ } else if (type === 'tool-use') {
304
+ // Tool execution started
305
+ const name = (data.name as string) || 'unknown';
306
+ const input =
307
+ typeof data.input === 'object' && data.input !== null
308
+ ? (data.input as Record<string, unknown>)
309
+ : {};
310
+ const filePath = (input.file_path as string) || (input.path as string) || '';
311
+ const command = (input.command as string) || '';
312
+ const pattern = (input.pattern as string) || '';
313
+ addActivityEvent(session, 'tool_use', {
314
+ command: command.slice(0, 120),
315
+ filePath: filePath.slice(0, 200),
316
+ name,
317
+ pattern: pattern.slice(0, 100),
318
+ tool: name,
319
+ });
320
+ } else if (type === 'tool-result') {
321
+ // Tool result received
322
+ const isError = data.isError === true;
323
+ const output = ((data.output as string) || '').slice(0, 200);
324
+ // Fall back to the last tool_use event's name when data.name is missing
325
+ let toolName = (data.name as string) || '';
326
+ if (!toolName) {
327
+ for (let i = events.length - 1; i >= 0; i--) {
328
+ if (events[i].type === 'tool_use' && events[i].data.name) {
329
+ toolName = events[i].data.name as string;
330
+ break;
331
+ }
332
+ }
333
+ }
334
+ addActivityEvent(session, 'tool_result', {
335
+ is_error: isError,
336
+ output,
337
+ status: isError ? 'error' : 'done',
338
+ tool: toolName,
339
+ });
340
+ if (isError) {
341
+ void tryGenerateSummary();
342
+ }
343
+ } else if (type === 'thinking') {
344
+ // Skip thinking blocks — too verbose for activity feed
345
+ } else if (type === 'error') {
346
+ addActivityEvent(session, 'error', {
347
+ message: (data.message as string) || 'Unknown error',
348
+ });
349
+ void tryGenerateSummary();
350
+ } else if (type === 'session-end') {
351
+ addActivityEvent(session, 'session_end', {});
352
+ void tryGenerateSummary();
353
+ }
354
+ // Ignore 'welcome' and other unknown types
355
+ }
356
+
357
+ /** Process a conversation message from the history batch. */
358
+ function processMessage(session: ActivitySessionRecord, msg: ActivitySessionMessage): void {
359
+ const timestamp = msg.timestamp || new Date().toISOString();
360
+
361
+ // Extract content text
362
+ let contentText = '';
363
+ if (typeof msg.content === 'string') {
364
+ contentText = msg.content;
365
+ } else if (Array.isArray(msg.content)) {
366
+ const textParts = msg.content
367
+ .filter((p) => p.type === 'text')
368
+ .map((p) => p.text || p.content || '');
369
+ contentText = textParts.join('');
370
+ }
371
+
372
+ if (msg.role === 'user') {
373
+ addActivityEvent(
374
+ session,
375
+ 'user_message',
376
+ {
377
+ text: contentText.slice(0, 150),
378
+ },
379
+ timestamp
380
+ );
381
+ } else if (msg.role === 'assistant' && Array.isArray(msg.content)) {
382
+ const toolUses = msg.content.filter((p) => p.type === 'tool_use');
383
+ for (const tu of toolUses) {
384
+ const raw = tu as unknown as Record<string, unknown>;
385
+ const input =
386
+ typeof raw.input === 'object' && raw.input !== null
387
+ ? (raw.input as Record<string, unknown>)
388
+ : {};
389
+ addActivityEvent(
390
+ session,
391
+ 'tool_use',
392
+ {
393
+ command: ((input.command as string) || '').slice(0, 120),
394
+ filePath: ((input.file_path as string) || (input.path as string) || '').slice(0, 200),
395
+ name: tu.name || 'unknown',
396
+ tool: tu.name || 'unknown',
397
+ },
398
+ timestamp
399
+ );
400
+ }
401
+ }
402
+ // Skip assistant text, system messages, and other roles for activity feed
403
+ }
404
+
405
+ // -- Internal: Summarization ----------------------------------------------
406
+
407
+ async function tryGenerateSummary(): Promise<void> {
408
+ if (summarizing) {
409
+ return;
410
+ }
411
+
412
+ const unsummarized = events.filter((e) => !e.summarized);
413
+ if (unsummarized.length === 0) {
414
+ return;
415
+ }
416
+
417
+ // Group by project
418
+ const byProject = new SvelteMap<string, ActivityEvent[]>();
419
+ for (const event of unsummarized) {
420
+ const project = event.projectName || 'Unknown';
421
+ if (!byProject.has(project)) {
422
+ byProject.set(project, []);
423
+ }
424
+ const bucket = byProject.get(project);
425
+ if (bucket) {
426
+ bucket.push(event);
427
+ }
428
+ }
429
+
430
+ // Only summarize projects with enough events
431
+ const ready = Array.from(byProject.entries()).filter(
432
+ ([, projectEvents]) => projectEvents.length >= SUMMARY_BATCH_SIZE
433
+ );
434
+
435
+ if (ready.length === 0) {
436
+ return;
437
+ }
438
+
439
+ summarizing = true;
440
+ try {
441
+ // Run up to 3 project summaries in parallel
442
+ const results = await Promise.allSettled(
443
+ ready.slice(0, 3).map(async ([projectName, projectEvents]) => {
444
+ const result = await summarizeEvents(projectEvents, projectName);
445
+ return { projectEvents, projectName, result };
446
+ })
447
+ );
448
+
449
+ for (const r of results) {
450
+ if (r.status !== 'fulfilled' || !r.value.result.text) {
451
+ continue;
452
+ }
453
+ const { projectEvents, projectName, result } = r.value;
454
+
455
+ // Detect AI unavailability from error flag
456
+ if (result.error?.includes('No AI provider')) {
457
+ aiAvailable = false;
458
+ }
459
+
460
+ const summary: ActivitySummary = {
461
+ eventIds: projectEvents.map((e) => e.id),
462
+ id: `sum-${++counter}`,
463
+ projectName,
464
+ text: result.text,
465
+ timestamp: new Date().toISOString(),
466
+ };
467
+
468
+ summaries = [...summaries, summary].slice(-MAX_SUMMARIES);
469
+
470
+ const ids = new Set(projectEvents.map((e) => e.id));
471
+ events = events.map((e) => (ids.has(e.id) ? { ...e, summarized: true } : e));
472
+ }
473
+ } catch (err) {
474
+ console.warn('[ActivityStore] Summarization failed:', err);
475
+ } finally {
476
+ summarizing = false;
477
+ }
478
+ }
@@ -0,0 +1,224 @@
1
+ // NeuroLink-powered event summarizer.
2
+ // Loads the NeuroLink SDK from CDN on first use, then generates
3
+ // rolling summaries of coding activity events.
4
+
5
+ import type { ActivityEvent, ActivitySummaryResult } from '$lib/types';
6
+
7
+ import { installFetchProxy } from '$lib/modules/client/neurolink/fetch-proxy';
8
+ import { detectActiveProvider } from '$lib/modules/client/neurolink/provider-config';
9
+
10
+ const NEUROLINK_CDN_URL = 'https://unpkg.com/@juspay/neurolink/dist/browser/neurolink.min.js';
11
+ const LOAD_FAILURE_COOLDOWN_MS = 60_000;
12
+ const MAX_LOAD_ATTEMPTS = 3;
13
+
14
+ // Lazy-loaded SDK instance
15
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
16
+ let sdk: null | { generate: (opts: Record<string, unknown>) => Promise<any> } = null;
17
+ let sdkPromise: null | Promise<typeof sdk> = null;
18
+ let loadAttempts = 0;
19
+ let nextRetryAt = 0;
20
+
21
+ /** Summarize a batch of events using NeuroLink. */
22
+ export async function summarizeEvents(
23
+ events: ActivityEvent[],
24
+ projectName?: string
25
+ ): Promise<ActivitySummaryResult> {
26
+ if (events.length === 0) {
27
+ return { error: null, text: '' };
28
+ }
29
+
30
+ let nlSdk: typeof sdk;
31
+ try {
32
+ nlSdk = await getSDK();
33
+ } catch {
34
+ const mapped: string[] = events.map((e) => str(e.data.tool) || e.type);
35
+ const tools = Array.from(new Set(mapped));
36
+ return {
37
+ error: 'AI SDK failed to load',
38
+ text: `${events.length} events: ${tools.join(', ')}`,
39
+ };
40
+ }
41
+
42
+ // Fallback: no SDK available — return raw count
43
+ if (!nlSdk) {
44
+ const mapped: string[] = events.map((e) => str(e.data.tool) || e.type);
45
+ const tools = Array.from(new Set(mapped));
46
+ return {
47
+ error: 'No AI provider configured',
48
+ text: `${events.length} events: ${tools.join(', ')}`,
49
+ };
50
+ }
51
+
52
+ const formatted = formatEvents(events);
53
+ const projectCtx = projectName ? `Project: ${projectName}\n` : '';
54
+ const prompt = `You are a coding activity summarizer. Given these events from active Claude Code sessions, write a 1-2 sentence summary (max 150 chars) of what's happening. Be specific — mention tool names, file names, and what's being accomplished.
55
+
56
+ ${projectCtx}Events:
57
+ ${formatted}
58
+
59
+ Summary:`;
60
+
61
+ try {
62
+ // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
63
+ const result: Record<string, unknown> = await nlSdk.generate({
64
+ input: { text: prompt },
65
+ maxTokens: 300,
66
+ ...(activeModel ? { model: activeModel } : {}),
67
+ ...(activeProvider ? { provider: activeProvider } : {}),
68
+ });
69
+ const text = str(result.content ?? result.text);
70
+ return { error: null, text: text.trim() || `${events.length} events processed` };
71
+ } catch (err) {
72
+ return {
73
+ error: err instanceof Error ? err.message : String(err),
74
+ text: `${events.length} events (summary unavailable)`,
75
+ };
76
+ }
77
+ }
78
+
79
+ function formatEventLine(e: ActivityEvent): string {
80
+ const d = e.data;
81
+ const project = e.projectName ? `[${e.projectName}] ` : '';
82
+ const tool = str(d.tool) || str(d.name) || '';
83
+ const filePath = str(d.filePath);
84
+ const command = str(d.command);
85
+ const pattern = str(d.pattern);
86
+
87
+ switch (e.type) {
88
+ case 'agent-idle':
89
+ case 'agent-question':
90
+ return `${project}${e.type}: ${str(d.message).slice(0, 80)}`;
91
+ case 'error':
92
+ return `${project}Error: ${str(d.error || d.message).slice(0, 100)}`;
93
+ case 'session_end':
94
+ return `${project}Session ended`;
95
+ case 'tool-completed':
96
+ return `${project}[${tool}] completed`;
97
+ case 'tool-failed':
98
+ return `${project}[${tool}] FAILED: ${str(d.error).slice(0, 80)}`;
99
+ case 'tool-started':
100
+ return `${project}[${tool}] started${filePath ? `: ${filePath}` : ''}`;
101
+ case 'tool_result': {
102
+ const status = d.is_error ? 'FAILED' : 'done';
103
+ return `${project}${tool ? `[${tool}] → ` : ''}${status}`;
104
+ }
105
+ case 'tool_use': {
106
+ const target = filePath || command || pattern || '';
107
+ return tool ? `${project}[${tool}] ${target}`.trim() : `${project}[tool] ${target}`.trim();
108
+ }
109
+ case 'user_message':
110
+ return `${project}User: ${str(d.text).slice(0, 80)}`;
111
+ default:
112
+ return `${project}${e.type}`;
113
+ }
114
+ }
115
+
116
+ /** Format events into a prompt string. */
117
+ function formatEvents(events: ActivityEvent[]): string {
118
+ return events.map(formatEventLine).join('\n');
119
+ }
120
+
121
+ // Track detected provider for generate() calls
122
+ let activeModel = '';
123
+ let activeProvider = '';
124
+
125
+ /** Load the NeuroLink SDK from CDN (once), using auto-detected provider. */
126
+ async function getSDK(): Promise<typeof sdk> {
127
+ if (sdk) {
128
+ return sdk;
129
+ }
130
+ // De-duplicate concurrent calls — share the in-flight load promise
131
+ if (sdkPromise) {
132
+ return sdkPromise;
133
+ }
134
+ // Cool down after repeated failures so a transient CDN blip doesn't
135
+ // permanently disable summaries. Once the cooldown expires, reset the
136
+ // attempt counter and try again.
137
+ if (loadAttempts >= MAX_LOAD_ATTEMPTS) {
138
+ if (Date.now() < nextRetryAt) {
139
+ return null;
140
+ }
141
+ loadAttempts = 0;
142
+ }
143
+ loadAttempts++;
144
+
145
+ sdkPromise = (async (): Promise<typeof sdk> => {
146
+ try {
147
+ // Install fetch proxy for CORS providers (anthropic, openai, mistral)
148
+ installFetchProxy();
149
+
150
+ // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
151
+ const mod = await import(/* @vite-ignore */ NEUROLINK_CDN_URL);
152
+
153
+ // Detect which provider has credentials available
154
+ const serverFlags = (window as unknown as Record<string, Record<string, boolean>>)
155
+ .__aiProviders;
156
+ const preferredProvider = (
157
+ window as unknown as Record<string, Record<string, Record<string, string>>>
158
+ ).process?.env?.NEUROLINK_PROVIDER;
159
+
160
+ const active = detectActiveProvider(serverFlags, preferredProvider);
161
+ if (!active) {
162
+ console.warn('[ActivityFeed] No AI provider configured');
163
+ return null;
164
+ }
165
+
166
+ // Proxy providers: inject dummy env vars so SDK validation passes.
167
+ // The fetch proxy strips these and injects real keys server-side.
168
+ const proc = (window as unknown as { process?: { env?: Record<string, string> } }).process;
169
+ if (proc?.env && serverFlags) {
170
+ if (serverFlags['google-ai'] && !proc.env.GOOGLE_AI_API_KEY) {
171
+ proc.env.GOOGLE_AI_API_KEY = 'proxy-via-server';
172
+ }
173
+ if (serverFlags.anthropic && !proc.env.ANTHROPIC_API_KEY) {
174
+ proc.env.ANTHROPIC_API_KEY = 'proxy-via-server';
175
+ }
176
+ if (serverFlags.openai && !proc.env.OPENAI_API_KEY) {
177
+ proc.env.OPENAI_API_KEY = 'proxy-via-server';
178
+ }
179
+ if (serverFlags.mistral && !proc.env.MISTRAL_API_KEY) {
180
+ proc.env.MISTRAL_API_KEY = 'proxy-via-server';
181
+ }
182
+ }
183
+
184
+ // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access, @typescript-eslint/no-unsafe-call
185
+ sdk = new mod.NeuroLink({ provider: active.provider }) as typeof sdk;
186
+ activeModel = active.model;
187
+ activeProvider = active.provider;
188
+ loadAttempts = 0; // reset on success
189
+ console.log(`[ActivityFeed] NeuroLink SDK loaded: ${active.provider}/${active.model}`);
190
+ return sdk;
191
+ } catch (err) {
192
+ console.warn(
193
+ '[ActivityFeed] NeuroLink SDK load failed (attempt',
194
+ loadAttempts,
195
+ '):',
196
+ err instanceof Error ? err.message : String(err)
197
+ );
198
+ // On the final attempt, start the cooldown window before allowing
199
+ // fresh retries. Earlier attempts can retry immediately on next call.
200
+ if (loadAttempts >= MAX_LOAD_ATTEMPTS) {
201
+ nextRetryAt = Date.now() + LOAD_FAILURE_COOLDOWN_MS;
202
+ }
203
+ return null;
204
+ } finally {
205
+ sdkPromise = null;
206
+ }
207
+ })();
208
+
209
+ return sdkPromise;
210
+ }
211
+
212
+ /** Coerce an unknown value to a plain string (never '[object Object]'). */
213
+ function str(v: unknown): string {
214
+ if (v === null || v === undefined) {
215
+ return '';
216
+ }
217
+ if (typeof v === 'string') {
218
+ return v;
219
+ }
220
+ if (typeof v === 'number' || typeof v === 'boolean') {
221
+ return String(v);
222
+ }
223
+ return JSON.stringify(v);
224
+ }