@juspay/shooter 1.4.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 (480) hide show
  1. package/.claude/hooks/notifier.cjs +15 -1
  2. package/README.md +132 -36
  3. package/bin/shooter.cjs +98 -29
  4. package/build/client/_app/immutable/assets/2.Dk9NfqnS.css +1 -0
  5. package/build/client/_app/immutable/assets/2.Dk9NfqnS.css.br +0 -0
  6. package/build/client/_app/immutable/assets/2.Dk9NfqnS.css.gz +0 -0
  7. package/build/client/_app/immutable/assets/3.DHxQoulp.css +1 -0
  8. package/build/client/_app/immutable/assets/3.DHxQoulp.css.br +0 -0
  9. package/build/client/_app/immutable/assets/3.DHxQoulp.css.gz +0 -0
  10. package/build/client/_app/immutable/assets/{3.DGDHCVnW.css → 4.D5l1JxgO.css} +1 -1
  11. package/build/client/_app/immutable/assets/4.D5l1JxgO.css.br +0 -0
  12. package/build/client/_app/immutable/assets/4.D5l1JxgO.css.gz +0 -0
  13. package/build/client/_app/immutable/assets/5.C5qz-NeI.css +1 -0
  14. package/build/client/_app/immutable/assets/5.C5qz-NeI.css.br +0 -0
  15. package/build/client/_app/immutable/assets/5.C5qz-NeI.css.gz +0 -0
  16. package/build/client/_app/immutable/chunks/1mEchsPO.js +1 -0
  17. package/build/client/_app/immutable/chunks/1mEchsPO.js.br +0 -0
  18. package/build/client/_app/immutable/chunks/1mEchsPO.js.gz +0 -0
  19. package/build/client/_app/immutable/chunks/B7X-vhXI.js +1 -0
  20. package/build/client/_app/immutable/chunks/B7X-vhXI.js.br +0 -0
  21. package/build/client/_app/immutable/chunks/B7X-vhXI.js.gz +0 -0
  22. package/build/client/_app/immutable/chunks/BRkqKgVG.js +1 -0
  23. package/build/client/_app/immutable/chunks/BRkqKgVG.js.br +0 -0
  24. package/build/client/_app/immutable/chunks/BRkqKgVG.js.gz +0 -0
  25. package/build/client/_app/immutable/chunks/BfJ-f-Tu.js +1 -0
  26. package/build/client/_app/immutable/chunks/BfJ-f-Tu.js.br +2 -0
  27. package/build/client/_app/immutable/chunks/BfJ-f-Tu.js.gz +0 -0
  28. package/build/client/_app/immutable/chunks/CGMJxf7r.js +1 -0
  29. package/build/client/_app/immutable/chunks/CGMJxf7r.js.br +0 -0
  30. package/build/client/_app/immutable/chunks/CGMJxf7r.js.gz +0 -0
  31. package/build/client/_app/immutable/chunks/{CZHsSL_X.js → CJFjKwJ7.js} +1 -1
  32. package/build/client/_app/immutable/chunks/CJFjKwJ7.js.br +0 -0
  33. package/build/client/_app/immutable/chunks/CJFjKwJ7.js.gz +0 -0
  34. package/build/client/_app/immutable/chunks/CNH2HlKj.js +20 -0
  35. package/build/client/_app/immutable/chunks/CNH2HlKj.js.br +0 -0
  36. package/build/client/_app/immutable/chunks/CNH2HlKj.js.gz +0 -0
  37. package/build/client/_app/immutable/chunks/CR6bkGJW.js +6 -0
  38. package/build/client/_app/immutable/chunks/CR6bkGJW.js.br +0 -0
  39. package/build/client/_app/immutable/chunks/CR6bkGJW.js.gz +0 -0
  40. package/build/client/_app/immutable/chunks/CVtJ6yRM.js +1 -0
  41. package/build/client/_app/immutable/chunks/CVtJ6yRM.js.br +0 -0
  42. package/build/client/_app/immutable/chunks/CVtJ6yRM.js.gz +0 -0
  43. package/build/client/_app/immutable/chunks/{CSoRdFvv.js → CaiJSUi3.js} +1 -1
  44. package/build/client/_app/immutable/chunks/CaiJSUi3.js.br +0 -0
  45. package/build/client/_app/immutable/chunks/CaiJSUi3.js.gz +0 -0
  46. package/build/client/_app/immutable/chunks/{DjsDGxCa.js → CmczWE_d.js} +4 -4
  47. package/build/client/_app/immutable/chunks/CmczWE_d.js.br +0 -0
  48. package/build/client/_app/immutable/chunks/CmczWE_d.js.gz +0 -0
  49. package/build/client/_app/immutable/chunks/{CDVSripB.js → CqfYvnci.js} +1 -1
  50. package/build/client/_app/immutable/chunks/CqfYvnci.js.br +0 -0
  51. package/build/client/_app/immutable/chunks/CqfYvnci.js.gz +0 -0
  52. package/build/client/_app/immutable/chunks/CsgHjHGZ.js +1 -0
  53. package/build/client/_app/immutable/chunks/CsgHjHGZ.js.br +0 -0
  54. package/build/client/_app/immutable/chunks/CsgHjHGZ.js.gz +0 -0
  55. package/build/client/_app/immutable/chunks/{UJOiqIYE.js → CtrCjGZT.js} +1 -1
  56. package/build/client/_app/immutable/chunks/CtrCjGZT.js.br +0 -0
  57. package/build/client/_app/immutable/chunks/CtrCjGZT.js.gz +0 -0
  58. package/build/client/_app/immutable/chunks/DDiOVAd8.js +61 -0
  59. package/build/client/_app/immutable/chunks/DDiOVAd8.js.br +0 -0
  60. package/build/client/_app/immutable/chunks/DDiOVAd8.js.gz +0 -0
  61. package/build/client/_app/immutable/chunks/DVl0sebP.js +2 -0
  62. package/build/client/_app/immutable/chunks/DVl0sebP.js.br +0 -0
  63. package/build/client/_app/immutable/chunks/DVl0sebP.js.gz +0 -0
  64. package/build/client/_app/immutable/chunks/EhLZwqfu.js +3 -0
  65. package/build/client/_app/immutable/chunks/EhLZwqfu.js.br +0 -0
  66. package/build/client/_app/immutable/chunks/EhLZwqfu.js.gz +0 -0
  67. package/build/client/_app/immutable/chunks/gQJcRhou.js +1 -0
  68. package/build/client/_app/immutable/chunks/gQJcRhou.js.br +0 -0
  69. package/build/client/_app/immutable/chunks/gQJcRhou.js.gz +0 -0
  70. package/build/client/_app/immutable/chunks/pRcLbE0d.js +1 -0
  71. package/build/client/_app/immutable/chunks/pRcLbE0d.js.br +0 -0
  72. package/build/client/_app/immutable/chunks/pRcLbE0d.js.gz +0 -0
  73. package/build/client/_app/immutable/chunks/{CF4lQ45j.js → y_g-KC7l.js} +1 -1
  74. package/build/client/_app/immutable/chunks/y_g-KC7l.js.br +0 -0
  75. package/build/client/_app/immutable/chunks/y_g-KC7l.js.gz +0 -0
  76. package/build/client/_app/immutable/entry/app.zJvbFXsj.js +2 -0
  77. package/build/client/_app/immutable/entry/app.zJvbFXsj.js.br +0 -0
  78. package/build/client/_app/immutable/entry/app.zJvbFXsj.js.gz +0 -0
  79. package/build/client/_app/immutable/entry/start.B2Jf5iFd.js +1 -0
  80. package/build/client/_app/immutable/entry/start.B2Jf5iFd.js.br +2 -0
  81. package/build/client/_app/immutable/entry/start.B2Jf5iFd.js.gz +0 -0
  82. package/build/client/_app/immutable/nodes/0.B_E4j3MX.js +1 -0
  83. package/build/client/_app/immutable/nodes/0.B_E4j3MX.js.br +0 -0
  84. package/build/client/_app/immutable/nodes/0.B_E4j3MX.js.gz +0 -0
  85. package/build/client/_app/immutable/nodes/1.B0oFqb8X.js +1 -0
  86. package/build/client/_app/immutable/nodes/1.B0oFqb8X.js.br +0 -0
  87. package/build/client/_app/immutable/nodes/1.B0oFqb8X.js.gz +0 -0
  88. package/build/client/_app/immutable/nodes/2.Bqul0XyM.js +13 -0
  89. package/build/client/_app/immutable/nodes/2.Bqul0XyM.js.br +0 -0
  90. package/build/client/_app/immutable/nodes/2.Bqul0XyM.js.gz +0 -0
  91. package/build/client/_app/immutable/nodes/3.CTqUQKSN.js +9 -0
  92. package/build/client/_app/immutable/nodes/3.CTqUQKSN.js.br +0 -0
  93. package/build/client/_app/immutable/nodes/3.CTqUQKSN.js.gz +0 -0
  94. package/build/client/_app/immutable/nodes/4.B_pbOZoD.js +4 -0
  95. package/build/client/_app/immutable/nodes/4.B_pbOZoD.js.br +0 -0
  96. package/build/client/_app/immutable/nodes/4.B_pbOZoD.js.gz +0 -0
  97. package/build/client/_app/immutable/nodes/5.CdLPNo5-.js +1 -0
  98. package/build/client/_app/immutable/nodes/5.CdLPNo5-.js.br +0 -0
  99. package/build/client/_app/immutable/nodes/5.CdLPNo5-.js.gz +0 -0
  100. package/build/client/_app/immutable/nodes/6.BvjUfHnH.js +1 -0
  101. package/build/client/_app/immutable/nodes/6.BvjUfHnH.js.br +0 -0
  102. package/build/client/_app/immutable/nodes/6.BvjUfHnH.js.gz +0 -0
  103. package/build/client/_app/immutable/nodes/{5.g3R-QfIW.js → 7.5K7Od8ba.js} +3 -3
  104. package/build/client/_app/immutable/nodes/7.5K7Od8ba.js.br +0 -0
  105. package/build/client/_app/immutable/nodes/7.5K7Od8ba.js.gz +0 -0
  106. package/build/client/_app/immutable/nodes/8.Bs1DrW0_.js +2 -0
  107. package/build/client/_app/immutable/nodes/8.Bs1DrW0_.js.br +0 -0
  108. package/build/client/_app/immutable/nodes/8.Bs1DrW0_.js.gz +0 -0
  109. package/build/client/_app/immutable/nodes/9.1fMlGdqv.js +2 -0
  110. package/build/client/_app/immutable/nodes/9.1fMlGdqv.js.br +0 -0
  111. package/build/client/_app/immutable/nodes/9.1fMlGdqv.js.gz +0 -0
  112. package/build/client/_app/version.json +1 -1
  113. package/build/client/_app/version.json.br +0 -0
  114. package/build/client/_app/version.json.gz +0 -0
  115. package/build/server/chunks/0-e1fgD9Mi.js +23 -0
  116. package/build/server/chunks/0-e1fgD9Mi.js.map +1 -0
  117. package/build/server/chunks/1-D2_XVthm.js +9 -0
  118. package/build/server/chunks/{1-BV7u1xGo.js.map → 1-D2_XVthm.js.map} +1 -1
  119. package/build/server/chunks/2-DADX86JZ.js +21 -0
  120. package/build/server/chunks/2-DADX86JZ.js.map +1 -0
  121. package/build/server/chunks/3-CHacdiCg.js +21 -0
  122. package/build/server/chunks/3-CHacdiCg.js.map +1 -0
  123. package/build/server/chunks/4-0UE_6Ep-.js +23 -0
  124. package/build/server/chunks/4-0UE_6Ep-.js.map +1 -0
  125. package/build/server/chunks/5-BBIP1PzX.js +24 -0
  126. package/build/server/chunks/5-BBIP1PzX.js.map +1 -0
  127. package/build/server/chunks/6-CWLNQu6F.js +9 -0
  128. package/build/server/chunks/6-CWLNQu6F.js.map +1 -0
  129. package/build/server/chunks/7-DmQ3B8uy.js +9 -0
  130. package/build/server/chunks/7-DmQ3B8uy.js.map +1 -0
  131. package/build/server/chunks/8-CnFVjQtZ.js +9 -0
  132. package/build/server/chunks/8-CnFVjQtZ.js.map +1 -0
  133. package/build/server/chunks/9-Dw7-P6aF.js +9 -0
  134. package/build/server/chunks/9-Dw7-P6aF.js.map +1 -0
  135. package/build/server/chunks/{Button-Cs1aE6ka.js → Button-WKgiLWZI.js} +4 -9
  136. package/build/server/chunks/Button-WKgiLWZI.js.map +1 -0
  137. package/build/server/chunks/{EmptyState-DDFH1K8g.js → EmptyState-BUBqASsp.js} +3 -3
  138. package/build/server/chunks/{EmptyState-DDFH1K8g.js.map → EmptyState-BUBqASsp.js.map} +1 -1
  139. package/build/server/chunks/{Icon-CEUrotA6.js → Icon-BNBAg85a.js} +3 -3
  140. package/build/server/chunks/Icon-BNBAg85a.js.map +1 -0
  141. package/build/server/chunks/{Shimmer-DB8W1zt6.js → Shimmer-C4uBVwxz.js} +2 -2
  142. package/build/server/chunks/{Shimmer-DB8W1zt6.js.map → Shimmer-C4uBVwxz.js.map} +1 -1
  143. package/build/server/chunks/{_error.svelte-uCOJNxvr.js → _error.svelte-DkIwmECt.js} +5 -5
  144. package/build/server/chunks/{_error.svelte-uCOJNxvr.js.map → _error.svelte-DkIwmECt.js.map} +1 -1
  145. package/build/server/chunks/{_layout.svelte-CtWmEJwe.js → _layout.svelte-DllETxmJ.js} +13 -7
  146. package/build/server/chunks/_layout.svelte-DllETxmJ.js.map +1 -0
  147. package/build/server/chunks/_page.svelte-BZSdLKE_.js +118 -0
  148. package/build/server/chunks/_page.svelte-BZSdLKE_.js.map +1 -0
  149. package/build/server/chunks/{_page.svelte-CxWcQ0Am.js → _page.svelte-Cmuco1mC.js} +84 -199
  150. package/build/server/chunks/_page.svelte-Cmuco1mC.js.map +1 -0
  151. package/build/server/chunks/{_page.svelte-BgevQjq1.js → _page.svelte-Co5sF7W-.js} +12 -11
  152. package/build/server/chunks/{_page.svelte-BgevQjq1.js.map → _page.svelte-Co5sF7W-.js.map} +1 -1
  153. package/build/server/chunks/{_page.svelte-DO4oa_LY.js → _page.svelte-CpL3R-VI.js} +8 -8
  154. package/build/server/chunks/{_page.svelte-DO4oa_LY.js.map → _page.svelte-CpL3R-VI.js.map} +1 -1
  155. package/build/server/chunks/_page.svelte-DDSzYLUs.js +137 -0
  156. package/build/server/chunks/_page.svelte-DDSzYLUs.js.map +1 -0
  157. package/build/server/chunks/_page.svelte-JIkgFUFf.js +26 -0
  158. package/build/server/chunks/_page.svelte-JIkgFUFf.js.map +1 -0
  159. package/build/server/chunks/{_page.svelte-CVq6tRb3.js → _page.svelte-Y9-O5a5w.js} +10 -9
  160. package/build/server/chunks/_page.svelte-Y9-O5a5w.js.map +1 -0
  161. package/build/server/chunks/{_page.svelte-BcZaKdX9.js → _page.svelte-fcX09N4d.js} +9 -9
  162. package/build/server/chunks/{_page.svelte-BcZaKdX9.js.map → _page.svelte-fcX09N4d.js.map} +1 -1
  163. package/build/server/chunks/{_server.ts-DYpJImqd.js → _server.ts-0Xr2fWaq.js} +9 -5
  164. package/build/server/chunks/_server.ts-0Xr2fWaq.js.map +1 -0
  165. package/build/server/chunks/{_server.ts-CTpcLUH8.js → _server.ts-2ixC-X3K.js} +20 -5
  166. package/build/server/chunks/_server.ts-2ixC-X3K.js.map +1 -0
  167. package/build/server/chunks/{_server.ts-CAxsWKvS.js → _server.ts-40c_epk8.js} +20 -4
  168. package/build/server/chunks/_server.ts-40c_epk8.js.map +1 -0
  169. package/build/server/chunks/{_server.ts-WhTJBEJy.js → _server.ts-A9_tRR-K.js} +5 -4
  170. package/build/server/chunks/{_server.ts-WhTJBEJy.js.map → _server.ts-A9_tRR-K.js.map} +1 -1
  171. package/build/server/chunks/_server.ts-BRAzC6W1.js +98 -0
  172. package/build/server/chunks/_server.ts-BRAzC6W1.js.map +1 -0
  173. package/build/server/chunks/{_server.ts-DB_Kg97c.js → _server.ts-BScvgttw.js} +24 -4
  174. package/build/server/chunks/_server.ts-BScvgttw.js.map +1 -0
  175. package/build/server/chunks/{_server.ts-Ch-6iOHp.js → _server.ts-B__YN2kX.js} +121 -87
  176. package/build/server/chunks/_server.ts-B__YN2kX.js.map +1 -0
  177. package/build/server/chunks/{_server.ts-tSpgyl1D.js → _server.ts-Bjbr7glm.js} +4 -3
  178. package/build/server/chunks/_server.ts-Bjbr7glm.js.map +1 -0
  179. package/build/server/chunks/{_server.ts-COu0vNpd.js → _server.ts-BrqaMMAa.js} +7 -6
  180. package/build/server/chunks/_server.ts-BrqaMMAa.js.map +1 -0
  181. package/build/server/chunks/{_server.ts-vekTmWAx.js → _server.ts-BuYyCrnF.js} +6 -4
  182. package/build/server/chunks/_server.ts-BuYyCrnF.js.map +1 -0
  183. package/build/server/chunks/{_server.ts-Deok2y88.js → _server.ts-ByIrRtCx.js} +132 -76
  184. package/build/server/chunks/_server.ts-ByIrRtCx.js.map +1 -0
  185. package/build/server/chunks/{_server.ts-DYvb9ijZ.js → _server.ts-ByPExYfO.js} +4 -3
  186. package/build/server/chunks/{_server.ts-DYvb9ijZ.js.map → _server.ts-ByPExYfO.js.map} +1 -1
  187. package/build/server/chunks/_server.ts-CjpQ10xh.js +123 -0
  188. package/build/server/chunks/_server.ts-CjpQ10xh.js.map +1 -0
  189. package/build/server/chunks/_server.ts-CyjDrcZN.js +21 -0
  190. package/build/server/chunks/_server.ts-CyjDrcZN.js.map +1 -0
  191. package/build/server/chunks/{_server.ts-DV8zTCF9.js → _server.ts-DOGUMzPx.js} +4 -3
  192. package/build/server/chunks/{_server.ts-DV8zTCF9.js.map → _server.ts-DOGUMzPx.js.map} +1 -1
  193. package/build/server/chunks/_server.ts-DZvfyuNj.js +15 -0
  194. package/build/server/chunks/_server.ts-DZvfyuNj.js.map +1 -0
  195. package/build/server/chunks/{_server.ts-XzT2UHM1.js → _server.ts-DkPPTUPo.js} +4 -3
  196. package/build/server/chunks/{_server.ts-XzT2UHM1.js.map → _server.ts-DkPPTUPo.js.map} +1 -1
  197. package/build/server/chunks/{auth-DeCdZ83n.js → auth-DuunT7Cg.js} +2 -2
  198. package/build/server/chunks/{auth-DeCdZ83n.js.map → auth-DuunT7Cg.js.map} +1 -1
  199. package/build/server/chunks/{client-BdGHe_hY.js → client-DRtPDkMh.js} +4 -4
  200. package/build/server/chunks/{client-BdGHe_hY.js.map → client-DRtPDkMh.js.map} +1 -1
  201. package/build/server/chunks/client2-bqqmu0b7.js +7 -0
  202. package/build/server/chunks/{client2-CCBGA-2V.js.map → client2-bqqmu0b7.js.map} +1 -1
  203. package/build/server/chunks/close-BGlLztTb.js +192 -0
  204. package/build/server/chunks/close-BGlLztTb.js.map +1 -0
  205. package/build/server/chunks/events-handler-Dm1mNPQP.js +20 -0
  206. package/build/server/chunks/events-handler-Dm1mNPQP.js.map +1 -0
  207. package/build/server/chunks/html-FW6Ia4bL.js +8 -0
  208. package/build/server/chunks/html-FW6Ia4bL.js.map +1 -0
  209. package/build/server/chunks/{shared-server-sSGG17Df.js → index-CoD1IJuy.js} +2 -11
  210. package/build/server/chunks/index-CoD1IJuy.js.map +1 -0
  211. package/build/server/chunks/{index-DwaY1cAm.js → index-DP9bWJrR.js} +2 -2
  212. package/build/server/chunks/{index-DwaY1cAm.js.map → index-DP9bWJrR.js.map} +1 -1
  213. package/build/server/chunks/{index-server-CrDaL06Y.js → index-server-BUmV4MIG.js} +2 -2
  214. package/build/server/chunks/index-server-BUmV4MIG.js.map +1 -0
  215. package/build/server/chunks/index-server2-BJrT0wnA.js +5 -0
  216. package/build/server/chunks/index-server2-BJrT0wnA.js.map +1 -0
  217. package/build/server/chunks/{index2-CgclKpUj.js → index2-D5Y19GKR.js} +2 -2
  218. package/build/server/chunks/index2-D5Y19GKR.js.map +1 -0
  219. package/build/server/chunks/{library-apns-BqJbvSKh.js → library-apns-Cf-E-DhM.js} +5 -2
  220. package/build/server/chunks/library-apns-Cf-E-DhM.js.map +1 -0
  221. package/build/server/chunks/providers-DtstoHQ0.js +17 -0
  222. package/build/server/chunks/providers-DtstoHQ0.js.map +1 -0
  223. package/build/server/chunks/{pty-manager-BQVB7IVj.js → pty-manager-TyMUpDA9.js} +41 -9
  224. package/build/server/chunks/pty-manager-TyMUpDA9.js.map +1 -0
  225. package/build/server/chunks/{root-DDSnEAZv.js → root-CATOR_0t.js} +2 -2
  226. package/build/server/chunks/root-CATOR_0t.js.map +1 -0
  227. package/build/server/chunks/shared-server-DaWdgxVh.js +11 -0
  228. package/build/server/chunks/shared-server-DaWdgxVh.js.map +1 -0
  229. package/build/server/chunks/{state.svelte-hBbXlUak.js → state.svelte-CftllyvC.js} +3 -3
  230. package/build/server/chunks/state.svelte-CftllyvC.js.map +1 -0
  231. package/build/server/chunks/{stores-DHNzYNpX.js → stores-BjL57aOK.js} +4 -4
  232. package/build/server/chunks/{stores-DHNzYNpX.js.map → stores-BjL57aOK.js.map} +1 -1
  233. package/build/server/index.js +173 -6
  234. package/build/server/index.js.map +1 -1
  235. package/build/server/manifest.js +53 -30
  236. package/build/server/manifest.js.map +1 -1
  237. package/package.json +28 -7
  238. package/scripts/dev.mjs +361 -0
  239. package/scripts/install.sh +133 -73
  240. package/scripts/{fix-generated-types.sh → postgen-types.sh} +2 -2
  241. package/scripts/setup.cjs +440 -244
  242. package/scripts/vercel-env-commands.sh +3 -3
  243. package/server.ts +3 -3
  244. package/src/app.html +163 -0
  245. package/src/lib/modules/client/activity/ActivityFeed.svelte +279 -0
  246. package/src/lib/modules/client/activity/index.ts +8 -0
  247. package/src/lib/modules/client/activity/store.svelte.ts +478 -0
  248. package/src/lib/modules/client/activity/summarizer.ts +224 -0
  249. package/src/lib/modules/client/common/Card.svelte +2 -9
  250. package/src/lib/modules/client/common/EmptyState.svelte +2 -20
  251. package/src/lib/modules/client/common/Icon.svelte +3 -7
  252. package/src/lib/modules/client/common/StatusBadge.svelte +2 -4
  253. package/src/lib/modules/client/common/config-guard.ts +22 -2
  254. package/src/lib/modules/client/common/index.ts +1 -1
  255. package/src/lib/modules/client/common/time.ts +27 -9
  256. package/src/lib/modules/client/dashboard/DashboardCard.svelte +374 -0
  257. package/src/lib/modules/client/dashboard/DashboardView.svelte +66 -0
  258. package/src/lib/modules/client/dashboard/index.ts +12 -0
  259. package/src/lib/modules/client/dashboard/store.svelte.ts +663 -0
  260. package/src/lib/modules/client/dashboard/summarizer.ts +205 -0
  261. package/src/lib/modules/client/neurolink/fetch-proxy.ts +70 -0
  262. package/src/lib/modules/client/neurolink/provider-config.ts +111 -0
  263. package/src/lib/modules/client/terminal/ChatView.svelte +46 -43
  264. package/src/lib/modules/client/terminal/CommandPalette.svelte +3 -12
  265. package/src/lib/modules/client/terminal/ConnectionStatus.svelte +3 -6
  266. package/src/lib/modules/client/terminal/LaunchSheet.svelte +10 -21
  267. package/src/lib/modules/client/terminal/QuickKeys.svelte +4 -11
  268. package/src/lib/modules/client/terminal/ShortcutsHelp.svelte +3 -6
  269. package/src/lib/modules/client/terminal/keyboard-shortcuts.ts +5 -7
  270. package/src/lib/modules/client/terminal/xterm-wrapper.ts +27 -47
  271. package/src/lib/modules/server/apn/library-apns.ts +6 -3
  272. package/src/lib/modules/server/apn/notification-history.ts +2 -2
  273. package/src/lib/modules/server/apn/notification-sessions.ts +1 -3
  274. package/src/lib/modules/server/apn/pending-requests.ts +1 -1
  275. package/src/lib/modules/server/apn/types.ts +2 -52
  276. package/src/lib/modules/server/cli/index.ts +1 -30
  277. package/src/lib/modules/server/cli/runner.ts +7 -15
  278. package/src/lib/modules/server/fcm/fcm-service.ts +2 -2
  279. package/src/lib/modules/server/sessions/jsonl-parser.ts +97 -42
  280. package/src/lib/modules/server/sessions/jsonl-reader.ts +69 -60
  281. package/src/lib/modules/server/sessions/opencode-reader.ts +1 -1
  282. package/src/lib/modules/server/sessions/process-detector.ts +72 -31
  283. package/src/lib/modules/server/sessions/types.ts +2 -42
  284. package/src/lib/modules/server/terminal/holder-client.ts +11 -35
  285. package/src/lib/modules/server/terminal/opencode-watcher.ts +16 -24
  286. package/src/lib/modules/server/terminal/pty-manager.ts +40 -45
  287. package/src/lib/modules/server/terminal/session-watcher.ts +15 -17
  288. package/src/lib/modules/server/terminal/terminal-store.ts +1 -1
  289. package/src/lib/modules/server/ws/events-handler.ts +1 -16
  290. package/src/lib/modules/server/ws/keepalive.ts +1 -5
  291. package/src/lib/modules/server/ws/server.ts +1 -1
  292. package/src/lib/modules/server/ws/session-handler.ts +20 -86
  293. package/src/lib/modules/server/ws/terminal-handler.ts +28 -51
  294. package/src/lib/modules/server/ws/ticket-store.ts +1 -1
  295. package/src/lib/modules/shared/providers.ts +21 -0
  296. package/src/lib/types/activity.ts +18 -0
  297. package/src/lib/types/apn.ts +43 -0
  298. package/src/lib/types/cli.ts +39 -0
  299. package/src/lib/types/common.ts +39 -0
  300. package/src/lib/types/dashboard.ts +4 -0
  301. package/src/lib/types/generated/Client.ts +1656 -0
  302. package/src/{generated/types → lib/types/generated}/WsProtocol.ts +344 -2
  303. package/src/lib/types/index.ts +28 -0
  304. package/src/lib/types/neurolink.ts +4 -0
  305. package/src/lib/types/server.ts +93 -0
  306. package/src/lib/types/sessions.ts +59 -0
  307. package/src/lib/types/terminal-client.ts +132 -0
  308. package/src/lib/types/ws.ts +161 -0
  309. package/src/routes/+error.svelte +7 -2
  310. package/src/routes/+layout.server.ts +9 -0
  311. package/src/routes/+layout.svelte +36 -7
  312. package/src/routes/+page.server.ts +7 -0
  313. package/src/routes/+page.svelte +85 -35
  314. package/src/routes/activity/+page.server.ts +7 -0
  315. package/src/routes/activity/+page.svelte +58 -0
  316. package/src/routes/api/health/+server.ts +32 -19
  317. package/src/routes/api/neurolink-proxy/+server.ts +136 -0
  318. package/src/routes/api/notify/+server.ts +159 -84
  319. package/src/routes/api/sessions/+server.ts +1 -1
  320. package/src/routes/api/sessions/connect/+server.ts +10 -6
  321. package/src/routes/api/terminals/+server.ts +20 -1
  322. package/src/routes/api/terminals/[id]/+server.ts +16 -2
  323. package/src/routes/api/webhook/+server.ts +5 -33
  324. package/src/routes/api/ws-ticket/+server.ts +4 -4
  325. package/src/routes/config/+page.server.ts +9 -0
  326. package/src/routes/config/+page.svelte +118 -25
  327. package/src/routes/neurolink/+page.server.ts +10 -0
  328. package/src/routes/neurolink/+page.svelte +331 -0
  329. package/src/routes/project/+page.svelte +17 -12
  330. package/src/routes/session/[id]/+page.svelte +146 -62
  331. package/src/routes/terminals/+page.svelte +2 -2
  332. package/src/routes/terminals/[id]/+page.svelte +99 -88
  333. package/svelte.config.js +1 -3
  334. package/tsconfig.json +1 -0
  335. package/build/client/_app/immutable/assets/2.CAShZ7lQ.css +0 -1
  336. package/build/client/_app/immutable/assets/2.CAShZ7lQ.css.br +0 -1
  337. package/build/client/_app/immutable/assets/2.CAShZ7lQ.css.gz +0 -0
  338. package/build/client/_app/immutable/assets/3.DGDHCVnW.css.br +0 -0
  339. package/build/client/_app/immutable/assets/3.DGDHCVnW.css.gz +0 -0
  340. package/build/client/_app/immutable/chunks/B5NAKyil.js +0 -20
  341. package/build/client/_app/immutable/chunks/B5NAKyil.js.br +0 -0
  342. package/build/client/_app/immutable/chunks/B5NAKyil.js.gz +0 -0
  343. package/build/client/_app/immutable/chunks/B8XegpSE.js +0 -1
  344. package/build/client/_app/immutable/chunks/B8XegpSE.js.br +0 -0
  345. package/build/client/_app/immutable/chunks/B8XegpSE.js.gz +0 -0
  346. package/build/client/_app/immutable/chunks/B8zoBsv3.js +0 -6
  347. package/build/client/_app/immutable/chunks/B8zoBsv3.js.br +0 -0
  348. package/build/client/_app/immutable/chunks/B8zoBsv3.js.gz +0 -0
  349. package/build/client/_app/immutable/chunks/BN1NjBrw.js +0 -1
  350. package/build/client/_app/immutable/chunks/BN1NjBrw.js.br +0 -0
  351. package/build/client/_app/immutable/chunks/BN1NjBrw.js.gz +0 -0
  352. package/build/client/_app/immutable/chunks/BOYo8yTr.js +0 -1
  353. package/build/client/_app/immutable/chunks/BOYo8yTr.js.br +0 -0
  354. package/build/client/_app/immutable/chunks/BOYo8yTr.js.gz +0 -0
  355. package/build/client/_app/immutable/chunks/Bu1aqm5j.js +0 -1
  356. package/build/client/_app/immutable/chunks/Bu1aqm5j.js.br +0 -0
  357. package/build/client/_app/immutable/chunks/Bu1aqm5j.js.gz +0 -0
  358. package/build/client/_app/immutable/chunks/CDVSripB.js.br +0 -0
  359. package/build/client/_app/immutable/chunks/CDVSripB.js.gz +0 -0
  360. package/build/client/_app/immutable/chunks/CF4lQ45j.js.br +0 -0
  361. package/build/client/_app/immutable/chunks/CF4lQ45j.js.gz +0 -0
  362. package/build/client/_app/immutable/chunks/CQjSATpv.js +0 -61
  363. package/build/client/_app/immutable/chunks/CQjSATpv.js.br +0 -0
  364. package/build/client/_app/immutable/chunks/CQjSATpv.js.gz +0 -0
  365. package/build/client/_app/immutable/chunks/CSoRdFvv.js.br +0 -0
  366. package/build/client/_app/immutable/chunks/CSoRdFvv.js.gz +0 -0
  367. package/build/client/_app/immutable/chunks/CZHsSL_X.js.br +0 -0
  368. package/build/client/_app/immutable/chunks/CZHsSL_X.js.gz +0 -0
  369. package/build/client/_app/immutable/chunks/DSU1n5N_.js +0 -1
  370. package/build/client/_app/immutable/chunks/DSU1n5N_.js.br +0 -0
  371. package/build/client/_app/immutable/chunks/DSU1n5N_.js.gz +0 -0
  372. package/build/client/_app/immutable/chunks/DVkn4r72.js +0 -1
  373. package/build/client/_app/immutable/chunks/DVkn4r72.js.br +0 -0
  374. package/build/client/_app/immutable/chunks/DVkn4r72.js.gz +0 -0
  375. package/build/client/_app/immutable/chunks/DjsDGxCa.js.br +0 -0
  376. package/build/client/_app/immutable/chunks/DjsDGxCa.js.gz +0 -0
  377. package/build/client/_app/immutable/chunks/UJOiqIYE.js.br +0 -0
  378. package/build/client/_app/immutable/chunks/UJOiqIYE.js.gz +0 -0
  379. package/build/client/_app/immutable/chunks/r0JawsZc.js +0 -2
  380. package/build/client/_app/immutable/chunks/r0JawsZc.js.br +0 -0
  381. package/build/client/_app/immutable/chunks/r0JawsZc.js.gz +0 -0
  382. package/build/client/_app/immutable/entry/app.DwWiuoEC.js +0 -2
  383. package/build/client/_app/immutable/entry/app.DwWiuoEC.js.br +0 -0
  384. package/build/client/_app/immutable/entry/app.DwWiuoEC.js.gz +0 -0
  385. package/build/client/_app/immutable/entry/start.DG8BMhrh.js +0 -1
  386. package/build/client/_app/immutable/entry/start.DG8BMhrh.js.br +0 -0
  387. package/build/client/_app/immutable/entry/start.DG8BMhrh.js.gz +0 -0
  388. package/build/client/_app/immutable/nodes/0.ejabgzDQ.js +0 -1
  389. package/build/client/_app/immutable/nodes/0.ejabgzDQ.js.br +0 -0
  390. package/build/client/_app/immutable/nodes/0.ejabgzDQ.js.gz +0 -0
  391. package/build/client/_app/immutable/nodes/1.BFK7Ubrr.js +0 -1
  392. package/build/client/_app/immutable/nodes/1.BFK7Ubrr.js.br +0 -0
  393. package/build/client/_app/immutable/nodes/1.BFK7Ubrr.js.gz +0 -0
  394. package/build/client/_app/immutable/nodes/2.DV3saFiY.js +0 -1
  395. package/build/client/_app/immutable/nodes/2.DV3saFiY.js.br +0 -0
  396. package/build/client/_app/immutable/nodes/2.DV3saFiY.js.gz +0 -0
  397. package/build/client/_app/immutable/nodes/3.3yohCM25.js +0 -3
  398. package/build/client/_app/immutable/nodes/3.3yohCM25.js.br +0 -0
  399. package/build/client/_app/immutable/nodes/3.3yohCM25.js.gz +0 -0
  400. package/build/client/_app/immutable/nodes/4.D6NIf10D.js +0 -1
  401. package/build/client/_app/immutable/nodes/4.D6NIf10D.js.br +0 -0
  402. package/build/client/_app/immutable/nodes/4.D6NIf10D.js.gz +0 -0
  403. package/build/client/_app/immutable/nodes/5.g3R-QfIW.js.br +0 -0
  404. package/build/client/_app/immutable/nodes/5.g3R-QfIW.js.gz +0 -0
  405. package/build/client/_app/immutable/nodes/6.DSpd_nYK.js +0 -2
  406. package/build/client/_app/immutable/nodes/6.DSpd_nYK.js.br +0 -0
  407. package/build/client/_app/immutable/nodes/6.DSpd_nYK.js.gz +0 -0
  408. package/build/client/_app/immutable/nodes/7.F9WBFTz2.js +0 -2
  409. package/build/client/_app/immutable/nodes/7.F9WBFTz2.js.br +0 -0
  410. package/build/client/_app/immutable/nodes/7.F9WBFTz2.js.gz +0 -0
  411. package/build/server/chunks/0-ePgrkfG9.js +0 -9
  412. package/build/server/chunks/0-ePgrkfG9.js.map +0 -1
  413. package/build/server/chunks/1-BV7u1xGo.js +0 -9
  414. package/build/server/chunks/2-3p1kyvjQ.js +0 -9
  415. package/build/server/chunks/2-3p1kyvjQ.js.map +0 -1
  416. package/build/server/chunks/3-Ck7ewhOX.js +0 -9
  417. package/build/server/chunks/3-Ck7ewhOX.js.map +0 -1
  418. package/build/server/chunks/4-ChFYfo_S.js +0 -9
  419. package/build/server/chunks/4-ChFYfo_S.js.map +0 -1
  420. package/build/server/chunks/5-q-tQLBBu.js +0 -9
  421. package/build/server/chunks/5-q-tQLBBu.js.map +0 -1
  422. package/build/server/chunks/6-BIaAbm8b.js +0 -9
  423. package/build/server/chunks/6-BIaAbm8b.js.map +0 -1
  424. package/build/server/chunks/7--TmbCgrH.js +0 -9
  425. package/build/server/chunks/7--TmbCgrH.js.map +0 -1
  426. package/build/server/chunks/Button-Cs1aE6ka.js.map +0 -1
  427. package/build/server/chunks/Icon-CEUrotA6.js.map +0 -1
  428. package/build/server/chunks/_layout.svelte-CtWmEJwe.js.map +0 -1
  429. package/build/server/chunks/_page.svelte-BdYynOck.js +0 -85
  430. package/build/server/chunks/_page.svelte-BdYynOck.js.map +0 -1
  431. package/build/server/chunks/_page.svelte-CVq6tRb3.js.map +0 -1
  432. package/build/server/chunks/_page.svelte-CxWcQ0Am.js.map +0 -1
  433. package/build/server/chunks/_server.ts-BStnNIcq.js +0 -34
  434. package/build/server/chunks/_server.ts-BStnNIcq.js.map +0 -1
  435. package/build/server/chunks/_server.ts-CAxsWKvS.js.map +0 -1
  436. package/build/server/chunks/_server.ts-COu0vNpd.js.map +0 -1
  437. package/build/server/chunks/_server.ts-CTpcLUH8.js.map +0 -1
  438. package/build/server/chunks/_server.ts-Cf84YIaW.js +0 -25
  439. package/build/server/chunks/_server.ts-Cf84YIaW.js.map +0 -1
  440. package/build/server/chunks/_server.ts-Ch-6iOHp.js.map +0 -1
  441. package/build/server/chunks/_server.ts-CtH0dhUp.js +0 -71
  442. package/build/server/chunks/_server.ts-CtH0dhUp.js.map +0 -1
  443. package/build/server/chunks/_server.ts-DB_Kg97c.js.map +0 -1
  444. package/build/server/chunks/_server.ts-DYpJImqd.js.map +0 -1
  445. package/build/server/chunks/_server.ts-Deok2y88.js.map +0 -1
  446. package/build/server/chunks/_server.ts-tSpgyl1D.js.map +0 -1
  447. package/build/server/chunks/_server.ts-vekTmWAx.js.map +0 -1
  448. package/build/server/chunks/client2-CCBGA-2V.js +0 -7
  449. package/build/server/chunks/index-server-CrDaL06Y.js.map +0 -1
  450. package/build/server/chunks/index2-CgclKpUj.js.map +0 -1
  451. package/build/server/chunks/library-apns-BqJbvSKh.js.map +0 -1
  452. package/build/server/chunks/pty-manager-BQVB7IVj.js.map +0 -1
  453. package/build/server/chunks/root-DDSnEAZv.js.map +0 -1
  454. package/build/server/chunks/shared-server-sSGG17Df.js.map +0 -1
  455. package/build/server/chunks/state.svelte-hBbXlUak.js.map +0 -1
  456. package/src/generated/types/Client.ts +0 -589
  457. package/src/lib/types/config.ts +0 -1
  458. /package/build/client/_app/immutable/assets/{4.BFUut--w.css → 6.BFUut--w.css} +0 -0
  459. /package/build/client/_app/immutable/assets/{4.BFUut--w.css.br → 6.BFUut--w.css.br} +0 -0
  460. /package/build/client/_app/immutable/assets/{4.BFUut--w.css.gz → 6.BFUut--w.css.gz} +0 -0
  461. /package/build/client/_app/immutable/assets/{5.BTOx7yt7.css → 7.BTOx7yt7.css} +0 -0
  462. /package/build/client/_app/immutable/assets/{5.BTOx7yt7.css.br → 7.BTOx7yt7.css.br} +0 -0
  463. /package/build/client/_app/immutable/assets/{5.BTOx7yt7.css.gz → 7.BTOx7yt7.css.gz} +0 -0
  464. /package/build/client/_app/immutable/assets/{6.eZGZN-BF.css → 8.eZGZN-BF.css} +0 -0
  465. /package/build/client/_app/immutable/assets/{6.eZGZN-BF.css.br → 8.eZGZN-BF.css.br} +0 -0
  466. /package/build/client/_app/immutable/assets/{6.eZGZN-BF.css.gz → 8.eZGZN-BF.css.gz} +0 -0
  467. /package/build/client/_app/immutable/assets/{7.DwS5ZHBh.css → 9.DwS5ZHBh.css} +0 -0
  468. /package/build/client/_app/immutable/assets/{7.DwS5ZHBh.css.br → 9.DwS5ZHBh.css.br} +0 -0
  469. /package/build/client/_app/immutable/assets/{7.DwS5ZHBh.css.gz → 9.DwS5ZHBh.css.gz} +0 -0
  470. /package/src/{generated/types → lib/types/generated}/API.ts +0 -0
  471. /package/src/{generated/types → lib/types/generated}/APN.ts +0 -0
  472. /package/src/{generated/types → lib/types/generated}/CLI.ts +0 -0
  473. /package/src/{generated/types → lib/types/generated}/Config.ts +0 -0
  474. /package/src/{generated/types → lib/types/generated}/Holder.ts +0 -0
  475. /package/src/{generated/types → lib/types/generated}/JWT.ts +0 -0
  476. /package/src/{generated/types → lib/types/generated}/Notification.ts +0 -0
  477. /package/src/{generated/types → lib/types/generated}/OpenCode.ts +0 -0
  478. /package/src/{generated/types → lib/types/generated}/Sessions.ts +0 -0
  479. /package/src/{generated/types → lib/types/generated}/Terminal.ts +0 -0
  480. /package/src/{generated/types → lib/types/generated}/index.ts +0 -0
@@ -12,17 +12,18 @@
12
12
  */
13
13
 
14
14
  import type {
15
+ ConversationMessage,
16
+ MessagePart,
15
17
  OpenCodeMessage,
16
18
  OpenCodePart,
17
19
  OpenCodePartData,
18
20
  OpenCodeSession,
19
- } from '$generated/types';
21
+ OpenCodeWatchState as WatchState,
22
+ } from '$lib/types';
20
23
 
21
24
  import Database from 'better-sqlite3';
22
25
  import * as fs from 'fs';
23
26
 
24
- import type { ConversationMessage, MessagePart } from '../sessions/types';
25
-
26
27
  import { resolveOpenCodeDbPath } from '../sessions/opencode-db-path';
27
28
 
28
29
  // ── Constants ────────────────────────────────────────────────────────
@@ -35,24 +36,6 @@ const POLL_INTERVAL_MS = 2000;
35
36
  /** Maximum parameters per SQLite IN clause (SQLite limit is 999). */
36
37
  const SQLITE_MAX_PARAMS = 500;
37
38
 
38
- // ── Per-session Watcher State ────────────────────────────────────────
39
- // WatchState is a runtime/behavioral type (callbacks, emittedSets,
40
- // intervalHandle) and stays local.
41
-
42
- interface WatchState {
43
- callbacks: Set<(messages: ConversationMessage[]) => void>;
44
- /** Set of message IDs we have already emitted, to avoid duplicates. */
45
- emittedMessageIds: Set<string>;
46
- /** Map of part ID to last-seen time_updated, to detect in-place updates. */
47
- emittedPartUpdatedAt: Map<string, number>;
48
- intervalHandle: ReturnType<typeof setInterval>;
49
- /** Highest time_created we have seen for messages (milliseconds). */
50
- lastMessageTime: number;
51
- /** Highest time_updated we have seen for parts (milliseconds). */
52
- lastPartTime: number;
53
- sessionId: string;
54
- }
55
-
56
39
  class OpenCodeWatcher {
57
40
  private watchers = new Map<string, WatchState>();
58
41
 
@@ -156,7 +139,10 @@ class OpenCodeWatcher {
156
139
  if (!partsByMessage.has(part.message_id)) {
157
140
  partsByMessage.set(part.message_id, []);
158
141
  }
159
- partsByMessage.get(part.message_id)!.push(part);
142
+ const bucket = partsByMessage.get(part.message_id);
143
+ if (bucket) {
144
+ bucket.push(part);
145
+ }
160
146
  }
161
147
 
162
148
  return this.buildMessages(messages, partsByMessage);
@@ -449,7 +435,10 @@ class OpenCodeWatcher {
449
435
  if (!partsByMessage.has(part.message_id)) {
450
436
  partsByMessage.set(part.message_id, []);
451
437
  }
452
- partsByMessage.get(part.message_id)!.push(part);
438
+ const bucket = partsByMessage.get(part.message_id);
439
+ if (bucket) {
440
+ bucket.push(part);
441
+ }
453
442
  }
454
443
 
455
444
  const newEntries = this.buildMessages(dedupedMessages, partsByMessage);
@@ -510,7 +499,10 @@ class OpenCodeWatcher {
510
499
  if (!partsByMessage.has(part.message_id)) {
511
500
  partsByMessage.set(part.message_id, []);
512
501
  }
513
- partsByMessage.get(part.message_id)!.push(part);
502
+ const bucket = partsByMessage.get(part.message_id);
503
+ if (bucket) {
504
+ bucket.push(part);
505
+ }
514
506
  }
515
507
 
516
508
  // Fetch the parent messages for context (batched to avoid SQLite param limit).
@@ -1,4 +1,9 @@
1
- import type { TerminalRecord } from '$generated/types';
1
+ import type {
2
+ ConversationMessage,
3
+ PtyManagedTerminal as ManagedTerminal,
4
+ PtyOutputBuffer as OutputBuffer,
5
+ TerminalRecord,
6
+ } from '$lib/types';
2
7
  import type WebSocket from 'ws';
3
8
 
4
9
  import { type ChildProcess, fork } from 'child_process';
@@ -7,48 +12,11 @@ import { existsSync, readdirSync, readFileSync, statSync, unlinkSync } from 'fs'
7
12
  import path from 'path';
8
13
  import { fileURLToPath } from 'url';
9
14
 
10
- import type { ConversationMessage } from '../sessions/types';
11
-
15
+ import { broadcastEvent } from '../ws/server.js';
12
16
  import { HolderClient } from './holder-client';
13
17
  import { openCodeWatcher } from './opencode-watcher';
14
18
  import { terminalStore } from './terminal-store';
15
19
 
16
- // ---------------------------------------------------------------------------
17
- // Types
18
- // ---------------------------------------------------------------------------
19
-
20
- interface ManagedTerminal {
21
- args: string[];
22
- clients: Set<WebSocket>;
23
- cols: number;
24
- command: string;
25
- createdAt: Date;
26
- currentCwd: null | string;
27
- cwd: string;
28
- exitCode: null | number;
29
- exitedAt: Date | null;
30
- holderPid: number;
31
- id: string;
32
- isActive: boolean;
33
- openCodeNoopCb: ((messages: ConversationMessage[]) => void) | null;
34
- openCodeSessionId: null | string;
35
- outputBuffers: Map<WebSocket, OutputBuffer>;
36
- pid: number;
37
- pollTimer: null | ReturnType<typeof setInterval>;
38
- pty: HolderClient;
39
- rows: number;
40
- scrollback: string;
41
- sessionFile: null | string;
42
- socketPath: string;
43
- status: 'exited' | 'running';
44
- watcherOffset: number;
45
- }
46
-
47
- interface OutputBuffer {
48
- data: string[];
49
- size: number;
50
- }
51
-
52
20
  export type { ManagedTerminal };
53
21
 
54
22
  // ---------------------------------------------------------------------------
@@ -195,7 +163,10 @@ class PtyManager {
195
163
  });
196
164
  });
197
165
 
198
- const holderPid = holder.pid!;
166
+ if (holder.pid === undefined || holder.pid === null) {
167
+ throw new Error(`Holder process forked but PID unavailable for terminal ${id}`);
168
+ }
169
+ const holderPid = holder.pid;
199
170
 
200
171
  // Connect to the holder via Unix socket
201
172
  const client = new HolderClient();
@@ -255,6 +226,13 @@ class PtyManager {
255
226
  this.startSessionDiscovery(terminal);
256
227
 
257
228
  this.terminals.set(id, terminal);
229
+
230
+ broadcastEvent({
231
+ command: terminal.command ?? command,
232
+ terminalId: id,
233
+ type: 'terminal-created',
234
+ });
235
+
258
236
  return terminal;
259
237
  }
260
238
 
@@ -281,11 +259,14 @@ class PtyManager {
281
259
  } catch {
282
260
  // Best effort
283
261
  }
284
- // Also kill the holder process directly
285
- try {
286
- process.kill(terminal.holderPid, 'SIGKILL');
287
- } catch {
288
- // Best effort — holder may already be gone
262
+ // Also kill the holder process directly (guard against invalid PIDs —
263
+ // process.kill(0) targets the current process group, -1 targets all)
264
+ if (terminal.holderPid > 0) {
265
+ try {
266
+ process.kill(terminal.holderPid, 'SIGKILL');
267
+ } catch {
268
+ // Best effort — holder may already be gone
269
+ }
289
270
  }
290
271
  }
291
272
 
@@ -397,6 +378,7 @@ class PtyManager {
397
378
  terminal.status = 'exited';
398
379
  terminal.exitedAt = new Date();
399
380
  terminalStore.markExited(id, null);
381
+ this.emitTerminalExited(id, null);
400
382
  return true;
401
383
  }
402
384
 
@@ -411,6 +393,7 @@ class PtyManager {
411
393
  terminal.status = 'exited';
412
394
  terminal.exitedAt = terminal.exitedAt ?? new Date();
413
395
  terminalStore.markExited(id, null);
396
+ this.emitTerminalExited(id, null);
414
397
  }
415
398
  }, SIGKILL_DELAY_MS);
416
399
 
@@ -577,6 +560,15 @@ class PtyManager {
577
560
  // Private: startSessionDiscovery — polling for session files
578
561
  // -----------------------------------------------------------------------
579
562
 
563
+ /** Broadcast a terminal-exited event to /ws/events for the activity feed. */
564
+ private emitTerminalExited(terminalId: string, exitCode: null | number): void {
565
+ broadcastEvent({
566
+ code: exitCode ?? null,
567
+ terminalId,
568
+ type: 'terminal-exited',
569
+ });
570
+ }
571
+
580
572
  /** Evict a terminal, freeing all resources. */
581
573
  private evict(id: string): void {
582
574
  const terminal = this.terminals.get(id);
@@ -1003,6 +995,8 @@ class PtyManager {
1003
995
  terminal.exitedAt = new Date();
1004
996
  terminalStore.markExited(terminal.id, exitCode);
1005
997
 
998
+ this.emitTerminalExited(terminal.id, exitCode);
999
+
1006
1000
  const exitMsg = JSON.stringify({
1007
1001
  code: exitCode,
1008
1002
  signal: null,
@@ -1019,6 +1013,7 @@ class PtyManager {
1019
1013
  terminal.status = 'exited';
1020
1014
  terminal.exitedAt = new Date();
1021
1015
  terminalStore.markOrphaned(terminal.id);
1016
+ this.emitTerminalExited(terminal.id, null);
1022
1017
  }
1023
1018
  });
1024
1019
  }
@@ -1,23 +1,16 @@
1
- import { watch as chokidarWatch, type FSWatcher } from 'chokidar';
1
+ import type {
2
+ ConversationMessage,
3
+ MessagePart,
4
+ OnNewEntries,
5
+ SessionWatchedFile as WatchedFile,
6
+ } from '$lib/types';
7
+
8
+ import { watch as chokidarWatch } from 'chokidar';
2
9
  import * as fs from 'fs';
3
10
  import * as path from 'path';
4
11
 
5
- import type { ConversationMessage, MessagePart } from '../sessions/types';
6
-
7
12
  import { parseJsonlText } from '../sessions/jsonl-parser';
8
13
 
9
- /**
10
- * Callback invoked when new JSONL entries are parsed from a watched file.
11
- */
12
- type OnNewEntries = (entries: ConversationMessage[]) => void;
13
-
14
- interface WatchedFile {
15
- callbacks: Set<OnNewEntries>;
16
- filePath: string;
17
- offset: number;
18
- watcher: FSWatcher;
19
- }
20
-
21
14
  // Path to Claude Code's project session data
22
15
  const CLAUDE_PROJECTS_DIR = path.join(process.env.HOME || '', '.claude', 'projects');
23
16
 
@@ -89,7 +82,10 @@ class SessionWatcher {
89
82
  continue;
90
83
  }
91
84
  try {
92
- entries.push(JSON.parse(trimmed));
85
+ const parsed: unknown = JSON.parse(trimmed);
86
+ if (typeof parsed === 'object' && parsed !== null && !Array.isArray(parsed)) {
87
+ entries.push(parsed as Record<string, unknown>);
88
+ }
93
89
  } catch {
94
90
  // skip malformed lines
95
91
  }
@@ -274,7 +270,9 @@ class SessionWatcher {
274
270
  }
275
271
 
276
272
  // Parse the new lines using the file's accumulated assistant turn state
277
- const assistantTurns = this.assistantTurnsPerFile.get(filePath) || new Map();
273
+ const assistantTurns: Map<string, { parts: MessagePart[]; timestamp: string }> =
274
+ this.assistantTurnsPerFile.get(filePath) ??
275
+ new Map<string, { parts: MessagePart[]; timestamp: string }>();
278
276
  const startIndex = this.messageIndexPerFile.get(filePath) || 0;
279
277
  const newText = completeLines.join('\n');
280
278
  const newMessages = parseJsonlText(newText, assistantTurns, startIndex);
@@ -7,7 +7,7 @@
7
7
  * Database location: ~/.shooter/shooter.db
8
8
  */
9
9
 
10
- import type { TerminalRecord } from '$generated/types';
10
+ import type { TerminalRecord } from '$lib/types';
11
11
 
12
12
  import Database from 'better-sqlite3';
13
13
  import * as fs from 'fs';
@@ -2,24 +2,9 @@
2
2
  // Manages the /ws/events channel: tracks connected clients and broadcasts
3
3
  // ShooterEvents to all listeners. No client-to-server messages are expected.
4
4
 
5
- import type { PermissionDecision, SessionSource } from '$generated/types';
5
+ import type { WireShooterEvent as ShooterEvent } from '$lib/types';
6
6
  import type { WebSocket } from 'ws';
7
7
 
8
- // ── Event types ─────────────────────────────────────────────────────
9
-
10
- export type ShooterEvent =
11
- | { code: null | number; terminalId: string; type: 'terminal-exited' }
12
- | { command: string; terminalId: string; type: 'terminal-created' }
13
- | { decision: PermissionDecision; requestId: string; type: 'permission-resolved' }
14
- | {
15
- input: Record<string, unknown>;
16
- requestId: string;
17
- tool: string;
18
- type: 'permission-requested';
19
- }
20
- | { project: string; sessionId: string; source: SessionSource; type: 'session-started' }
21
- | { sessionId: string; summary: string; type: 'session-ended' };
22
-
23
8
  // ── Connection tracking ─────────────────────────────────────────────
24
9
 
25
10
  /** All clients subscribed to the global events channel. */
@@ -6,6 +6,7 @@
6
6
  // Cloudflare Tunnel closes idle WebSocket connections after ~100 seconds,
7
7
  // so 30-second pings keep connections alive through the tunnel.
8
8
 
9
+ import type { PendingPong } from '$lib/types';
9
10
  import type { WebSocket } from 'ws';
10
11
 
11
12
  import { getAllConnections } from './server.js';
@@ -24,11 +25,6 @@ let pingInterval: null | ReturnType<typeof setInterval> = null;
24
25
  * Stores the timeout timer and the listener functions so they can be
25
26
  * removed cleanly when stopKeepalive() is called mid-cycle.
26
27
  */
27
- interface PendingPong {
28
- onClose: () => void;
29
- onPong: () => void;
30
- timer: ReturnType<typeof setTimeout>;
31
- }
32
28
  const pendingPongs = new Map<WebSocket, PendingPong>();
33
29
 
34
30
  // ── Public API ───────────────────────────────────────────────────────
@@ -16,7 +16,7 @@ import {
16
16
  } from './events-handler.js';
17
17
  import { handleSessionConnection } from './session-handler.js';
18
18
  import { handleTerminalConnection } from './terminal-handler.js';
19
- export type { ShooterEvent } from './events-handler.js';
19
+ export type { WireShooterEvent as ShooterEvent } from '$lib/types';
20
20
 
21
21
  // ── Connection tracking ──────────────────────────────────────────────
22
22
 
@@ -3,98 +3,31 @@
3
3
  // on connect and streams new messages (text, tool-use, tool-result,
4
4
  // thinking) as they appear.
5
5
 
6
- import type { MessageRole, TextContentBlock } from '$generated/types';
6
+ import type {
7
+ WireSessionClientMessage as ClientMessage,
8
+ WsConnectionState as ConnectionState,
9
+ ConversationMessage,
10
+ WireHistoryMessage as HistoryMessage,
11
+ WireHistoryPart as HistoryPart,
12
+ SessionManagedTerminal as ManagedTerminal,
13
+ MessagePart,
14
+ SessionPtyManagerFullLike as PtyManagerFullLike,
15
+ SessionPtyManagerLike as PtyManagerLike,
16
+ WireSessionServerMessage as ServerMessage,
17
+ SessionWatcherLike,
18
+ TextContentBlock,
19
+ } from '$lib/types';
7
20
  import type { WebSocket } from 'ws';
8
21
 
9
22
  import * as fs from 'fs';
10
23
  import * as path from 'path';
11
24
 
12
- import type { ConversationMessage, MessagePart } from '../sessions/types';
13
-
14
- // ── Types ────────────────────────────────────────────────────────────
15
-
16
- /** Inbound messages from the client. */
17
- type ClientMessage =
18
- | { sessionId: string; type: 'subscribe' }
19
- | { text: string; type: 'send-input' }
20
- | { type: 'cancel' };
21
-
22
- /** A message in the history payload. */
23
- interface HistoryMessage {
24
- content: HistoryPart[];
25
- id: string;
26
- role: MessageRole;
27
- timestamp: string;
28
- }
29
-
30
- /** A single part within a history message — discriminated union. */
31
- type HistoryPart =
32
- | { content: string; type: 'text' }
33
- | { content: string; type: 'thinking' }
34
- | { id: string; input: Record<string, unknown>; toolName: string; type: 'tool_use' }
35
- | { isError: boolean; output: string; toolUseId: string; type: 'tool_result' };
36
-
37
- interface ManagedTerminal {
38
- id: string;
39
- openCodeSessionId: null | string;
40
- pty: {
41
- pid: number;
42
- write: (data: string) => void;
43
- };
44
- sessionFile: null | string;
45
- status: 'exited' | 'running';
46
- }
47
-
48
- /** Extended PTY manager interface with list() for UUID-based terminal search. */
49
- interface PtyManagerFullLike extends PtyManagerLike {
50
- list: () => ManagedTerminal[];
51
- }
52
-
53
- interface PtyManagerLike {
54
- getTerminal: (id: string) => ManagedTerminal | undefined;
55
- }
56
-
57
- // ── PTY Manager type ─────────────────────────────────────────────────
58
-
59
- /** Outbound messages to the client. */
60
- type ServerMessage =
61
- | { content: TextContentBlock[]; role: MessageRole; timestamp: string; type: 'message' }
62
- | {
63
- id: string;
64
- input: Record<string, unknown>;
65
- name: string;
66
- status: 'running';
67
- type: 'tool-use';
68
- }
69
- | { id: string; isError: boolean; output: string; status: 'done'; type: 'tool-result' }
70
- | { message: string; type: 'error' }
71
- | { messages: HistoryMessage[]; type: 'history' }
72
- | { text: string; type: 'thinking' }
73
- | { type: 'session-end' };
74
-
75
- interface SessionWatcherLike {
76
- getHistory: (sessionFile: string) => ConversationMessage[];
77
- subscribe: (
78
- sessionFile: string,
79
- callback: (messages: ConversationMessage[]) => void
80
- ) => () => void;
81
- }
82
-
83
25
  // ── Module-level references ──────────────────────────────────────────
84
26
 
85
27
  let _ptyManager: null | PtyManagerLike = null;
86
28
  let _ptyManagerFull: null | PtyManagerFullLike = null;
87
29
  let _sessionWatcher: null | SessionWatcherLike = null;
88
30
 
89
- /** Per-connection state tracked for cleanup. */
90
- interface ConnectionState {
91
- /** True when the session is file-only (no terminal backing it). */
92
- isExternalSession: boolean;
93
- retryInterval: null | ReturnType<typeof setInterval>;
94
- terminalId: string;
95
- unsubscribe: (() => void) | null;
96
- }
97
-
98
31
  /**
99
32
  * Handle a new WebSocket connection on the `/ws/session/:id` channel.
100
33
  * Accepts BOTH Shooter terminal IDs and external Claude Code session UUIDs.
@@ -285,7 +218,7 @@ function findTerminalBySessionUuid(uuid: string): ManagedTerminal | undefined {
285
218
  // module-level _ptyManagerFull reference if available.
286
219
  if (_ptyManagerFull) {
287
220
  for (const t of _ptyManagerFull.list()) {
288
- if (t.sessionFile && t.sessionFile.includes(`${uuid}.jsonl`)) {
221
+ if (t.sessionFile?.includes(`${uuid}.jsonl`)) {
289
222
  return _ptyManager.getTerminal(t.id);
290
223
  }
291
224
  }
@@ -296,7 +229,7 @@ function findTerminalBySessionUuid(uuid: string): ManagedTerminal | undefined {
296
229
  /** Parse and validate an inbound client message. */
297
230
  function parseClientMessage(raw: string): ClientMessage | null {
298
231
  try {
299
- const msg = JSON.parse(raw);
232
+ const msg = JSON.parse(raw) as Record<string, unknown>;
300
233
  if (!msg || typeof msg !== 'object' || typeof msg.type !== 'string') {
301
234
  return null;
302
235
  }
@@ -589,7 +522,8 @@ function wireClientMessages(ws: WebSocket, state: ConnectionState): void {
589
522
  case 'send-input': {
590
523
  if (state.isExternalSession) {
591
524
  safeSend(ws, {
592
- message: 'Cannot send input — this is a read-only session. Connect to a terminal first.',
525
+ message:
526
+ 'Cannot send input — this is a read-only session. Connect to a terminal first.',
593
527
  type: 'error',
594
528
  });
595
529
  return;
@@ -615,8 +549,8 @@ function wireClientMessages(ws: WebSocket, state: ConnectionState): void {
615
549
  }
616
550
 
617
551
  // Try terminal first, then external
618
- const newTerminal = _ptyManager?.getTerminal(msg.sessionId)
619
- ?? findTerminalBySessionUuid(msg.sessionId);
552
+ const newTerminal =
553
+ _ptyManager?.getTerminal(msg.sessionId) ?? findTerminalBySessionUuid(msg.sessionId);
620
554
 
621
555
  if (newTerminal) {
622
556
  state.terminalId = newTerminal.id;
@@ -2,25 +2,14 @@
2
2
  // Relays terminal output to connected clients and routes client input
3
3
  // (keystrokes, resize, signals) back to the PTY.
4
4
 
5
- import type { TerminalSignal } from '$generated/types';
5
+ import type {
6
+ WireTerminalClientMessage as ClientMessage,
7
+ TerminalPtyManagerLike as PtyManagerLike,
8
+ WireTerminalServerMessage as ServerMessage,
9
+ TerminalSignal,
10
+ } from '$lib/types';
6
11
  import type { WebSocket } from 'ws';
7
12
 
8
- // ── Types ────────────────────────────────────────────────────────────
9
-
10
- /** Inbound messages from the client. */
11
- type ClientMessage =
12
- | { cols: number; rows: number; type: 'resize' }
13
- | { data: string; type: 'input' }
14
- | { signal: TerminalSignal; type: 'signal' };
15
-
16
- /** Outbound messages to the client. */
17
- type ServerMessage =
18
- | { bytes: number; type: 'output-dropped' }
19
- | { chunk: number; data: string; total: number; type: 'scrollback' }
20
- | { code: null | number; signal: null | string; type: 'exit' }
21
- | { data: string; type: 'output' }
22
- | { message: string; type: 'error' };
23
-
24
13
  // ── Constants ────────────────────────────────────────────────────────
25
14
 
26
15
  /** Signal name → numeric code for process.kill(). */
@@ -30,28 +19,6 @@ const SIGNAL_MAP: Record<string, NodeJS.Signals> = {
30
19
  SIGTSTP: 'SIGTSTP',
31
20
  };
32
21
 
33
- // ── PTY Manager type ─────────────────────────────────────────────────
34
- // Minimal duck-typed shape matching the real pty-manager singleton.
35
-
36
- interface ManagedTerminal {
37
- clients: Set<WebSocket>;
38
- exitCode: null | number;
39
- id: string;
40
- pty: {
41
- kill: (signal: string) => void;
42
- pid: number;
43
- resize: (cols: number, rows: number) => void;
44
- write: (data: string) => void;
45
- };
46
- status: 'exited' | 'running';
47
- }
48
-
49
- interface PtyManagerLike {
50
- attach: (id: string, ws: WebSocket) => boolean;
51
- detach: (id: string, ws: WebSocket) => boolean;
52
- getTerminal: (id: string) => ManagedTerminal | undefined;
53
- }
54
-
55
22
  // Placeholder: will be replaced with the real ptyManager singleton import.
56
23
  // import { ptyManager } from '../terminal/pty-manager';
57
24
  let _ptyManager: null | PtyManagerLike = null;
@@ -153,8 +120,13 @@ export function setPtyManager(manager: PtyManagerLike): void {
153
120
  /** Parse and validate an inbound client message. Returns null for invalid messages. */
154
121
  function parseClientMessage(raw: string): ClientMessage | null {
155
122
  try {
156
- const msg = JSON.parse(raw);
157
- if (!msg || typeof msg !== 'object' || typeof msg.type !== 'string') {
123
+ const parsed: unknown = JSON.parse(raw);
124
+ if (!parsed || typeof parsed !== 'object') {
125
+ return null;
126
+ }
127
+
128
+ const msg = parsed as Record<string, unknown>;
129
+ if (typeof msg.type !== 'string') {
158
130
  return null;
159
131
  }
160
132
 
@@ -164,27 +136,32 @@ function parseClientMessage(raw: string): ClientMessage | null {
164
136
  return null;
165
137
  }
166
138
  return { data: msg.data, type: 'input' };
167
- case 'resize':
139
+ case 'resize': {
140
+ const cols = msg.cols;
141
+ const rows = msg.rows;
168
142
  if (
169
- typeof msg.cols !== 'number' ||
170
- typeof msg.rows !== 'number' ||
171
- !Number.isFinite(msg.cols) ||
172
- !Number.isFinite(msg.rows)
143
+ typeof cols !== 'number' ||
144
+ typeof rows !== 'number' ||
145
+ !Number.isFinite(cols) ||
146
+ !Number.isFinite(rows)
173
147
  ) {
174
148
  return null;
175
149
  }
176
- if (msg.cols < 1 || msg.rows < 1 || msg.cols > 500 || msg.rows > 200) {
150
+ if (cols < 1 || rows < 1 || cols > 500 || rows > 200) {
177
151
  return null;
178
152
  }
179
- return { cols: Math.floor(msg.cols), rows: Math.floor(msg.rows), type: 'resize' };
180
- case 'signal':
181
- if (typeof msg.signal !== 'string' || !Object.hasOwn(SIGNAL_MAP, msg.signal)) {
153
+ return { cols: Math.floor(cols), rows: Math.floor(rows), type: 'resize' };
154
+ }
155
+ case 'signal': {
156
+ const signal = msg.signal;
157
+ if (typeof signal !== 'string' || !Object.hasOwn(SIGNAL_MAP, signal)) {
182
158
  return null;
183
159
  }
184
160
  return {
185
- signal: msg.signal as TerminalSignal,
161
+ signal: signal as TerminalSignal,
186
162
  type: 'signal',
187
163
  };
164
+ }
188
165
  default:
189
166
  return null;
190
167
  }
@@ -5,7 +5,7 @@
5
5
  // This avoids putting the long-lived API_KEY in WebSocket URL query parameters,
6
6
  // which would appear in proxy logs, Cloudflare access logs, and browser history.
7
7
 
8
- import type { Ticket } from '$generated/types';
8
+ import type { Ticket } from '$lib/types';
9
9
 
10
10
  import { randomBytes } from 'crypto';
11
11
 
@@ -0,0 +1,21 @@
1
+ import type { ProviderId } from '$lib/types';
2
+
3
+ /** Env key names required for each provider to be considered configured. */
4
+ export const PROVIDER_ENV_KEYS: Record<ProviderId, string[]> = {
5
+ anthropic: ['ANTHROPIC_API_KEY'],
6
+ 'google-ai': ['GOOGLE_AI_API_KEY'],
7
+ litellm: ['LITELLM_API_KEY', 'LITELLM_BASE_URL'],
8
+ mistral: ['MISTRAL_API_KEY'],
9
+ openai: ['OPENAI_API_KEY'],
10
+ };
11
+
12
+ /** Check which providers have credentials configured. */
13
+ export function getProviderAvailability(
14
+ env: Record<string, string | undefined>
15
+ ): Record<ProviderId, boolean> {
16
+ const result = {} as Record<ProviderId, boolean>;
17
+ for (const [id, keys] of Object.entries(PROVIDER_ENV_KEYS)) {
18
+ result[id as ProviderId] = keys.every((k) => Boolean(env[k]?.trim()));
19
+ }
20
+ return result;
21
+ }
@@ -0,0 +1,18 @@
1
+ // Activity feed types that require union types not expressible in type-crafter YAML.
2
+
3
+ /** A single content block within a WebSocket session message. */
4
+ export interface ActivityContentBlock {
5
+ content?: string;
6
+ is_error?: boolean;
7
+ name?: string;
8
+ text?: string;
9
+ type: string;
10
+ }
11
+
12
+ /** A conversation message from a Claude Code session history batch.
13
+ * Uses a union type (string | array) which the YAML schema cannot express. */
14
+ export interface ActivitySessionMessage {
15
+ content: ActivityContentBlock[] | string;
16
+ role: string;
17
+ timestamp?: string;
18
+ }