@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
@@ -7,7 +7,51 @@
7
7
  * eliminates drift between the two code paths.
8
8
  */
9
9
 
10
- import type { ConversationMessage, MessagePart } from './types';
10
+ import type { ConversationMessage, MessagePart } from '$lib/types';
11
+
12
+ /* ------------------------------------------------------------------ */
13
+ /* Type guards & helpers for untyped parsed JSON */
14
+ /* ------------------------------------------------------------------ */
15
+
16
+ /** Extract text from a tool-result content field (string or array of {type,text}). */
17
+ function extractToolResultText(content: unknown): string {
18
+ if (typeof content === 'string') {
19
+ return content;
20
+ }
21
+ if (Array.isArray(content)) {
22
+ return (content as unknown[])
23
+ .filter((c): c is Record<string, unknown> => isRecord(c) && c.type === 'text')
24
+ .map((c) => {
25
+ const text = c.text;
26
+ return typeof text === 'string' ? text : '';
27
+ })
28
+ .join('\n');
29
+ }
30
+ return '';
31
+ }
32
+
33
+ /** Narrow an unknown value to a plain object with string keys. */
34
+ function isRecord(value: unknown): value is Record<string, unknown> {
35
+ return typeof value === 'object' && value !== null && !Array.isArray(value);
36
+ }
37
+
38
+ /** Safely read a string property from a record (returns '' on miss). */
39
+ function str(obj: Record<string, unknown>, key: string): string {
40
+ const v = obj[key];
41
+ return typeof v === 'string' ? v : '';
42
+ }
43
+
44
+ /** Coerce unknown array-ish content into Record<string, unknown>[]. */
45
+ function toContentBlocks(raw: unknown): Record<string, unknown>[] {
46
+ if (Array.isArray(raw)) {
47
+ return (raw as unknown[]).filter((item): item is Record<string, unknown> => isRecord(item));
48
+ }
49
+ // Single value — wrap it
50
+ if (isRecord(raw)) {
51
+ return [raw];
52
+ }
53
+ return [];
54
+ }
11
55
 
12
56
  /**
13
57
  * Internal event types that should be skipped during parsing.
@@ -62,53 +106,61 @@ export function parseJsonlLine(
62
106
  const messages: ConversationMessage[] = [];
63
107
  const assistantCompleted: ConversationMessage[] = [];
64
108
 
65
- const entry = JSON.parse(line);
66
- const entryType = entry.type;
109
+ const entry: unknown = JSON.parse(line);
110
+ if (!isRecord(entry)) {
111
+ return { assistantCompleted, messages };
112
+ }
113
+
114
+ const entryType = str(entry, 'type');
67
115
 
68
116
  // Skip known internal event types that don't represent conversation content
69
117
  if (SKIP_EVENT_TYPES.has(entryType)) {
70
118
  return { assistantCompleted, messages };
71
119
  }
72
120
 
121
+ const entryTimestamp = str(entry, 'timestamp');
122
+ const entryUuid = str(entry, 'uuid');
123
+
73
124
  if (entryType === 'user') {
74
- const msg = entry.message;
125
+ const msg = isRecord(entry.message) ? entry.message : null;
75
126
  if (!msg?.content) {
76
127
  return { assistantCompleted, messages };
77
128
  }
78
129
 
79
130
  const parts: MessagePart[] = [];
80
- const content = Array.isArray(msg.content) ? msg.content : [msg.content];
81
-
82
- for (const block of content) {
83
- if (typeof block === 'string') {
84
- parts.push({ content: block, type: 'text' });
85
- } else if (block.type === 'text') {
86
- parts.push({ content: block.text || '', type: 'text' });
87
- } else if (block.type === 'tool_result') {
88
- let output = '';
89
- if (typeof block.content === 'string') {
90
- output = block.content;
91
- } else if (Array.isArray(block.content)) {
92
- output = block.content
93
- .filter((c: { type: string }) => c.type === 'text')
94
- .map((c: { text: string }) => c.text)
95
- .join('\n');
131
+ const blocks = toContentBlocks(msg.content);
132
+
133
+ // Handle bare-string content items (not wrapped in a block)
134
+ if (Array.isArray(msg.content)) {
135
+ for (const item of msg.content as unknown[]) {
136
+ if (typeof item === 'string') {
137
+ parts.push({ content: item, type: 'text' });
96
138
  }
97
- if (entry.toolUseResult?.content) {
98
- const trc = entry.toolUseResult.content;
99
- if (typeof trc === 'string') {
100
- output = trc;
101
- } else if (Array.isArray(trc)) {
102
- output = trc
103
- .filter((c: { type: string }) => c.type === 'text')
104
- .map((c: { text: string }) => c.text)
105
- .join('\n');
106
- }
139
+ }
140
+ } else if (typeof msg.content === 'string') {
141
+ parts.push({ content: msg.content, type: 'text' });
142
+ }
143
+
144
+ for (const block of blocks) {
145
+ const blockType = str(block, 'type');
146
+ if (!blockType) {
147
+ continue;
148
+ }
149
+ if (blockType === 'text') {
150
+ parts.push({ content: str(block, 'text'), type: 'text' });
151
+ } else if (blockType === 'tool_result') {
152
+ let output = extractToolResultText(block.content);
153
+
154
+ // Check for toolUseResult override
155
+ const toolUseResult = isRecord(entry.toolUseResult) ? entry.toolUseResult : null;
156
+ if (toolUseResult?.content !== undefined) {
157
+ output = extractToolResultText(toolUseResult.content);
107
158
  }
159
+
108
160
  parts.push({
109
- isError: block.is_error || false,
161
+ isError: typeof block.is_error === 'boolean' ? block.is_error : false,
110
162
  output: output.slice(0, 2000),
111
- toolUseId: block.tool_use_id || '',
163
+ toolUseId: str(block, 'tool_use_id'),
112
164
  type: 'tool_result',
113
165
  });
114
166
  }
@@ -116,41 +168,44 @@ export function parseJsonlLine(
116
168
 
117
169
  if (parts.length > 0 && parts.some((p) => p.type === 'text')) {
118
170
  messages.push({
119
- id: entry.uuid || `user-${messageIndex}`,
171
+ id: entryUuid || `user-${messageIndex}`,
120
172
  parts: parts.filter((p) => p.type === 'text'),
121
173
  role: 'user',
122
- timestamp: entry.timestamp || '',
174
+ timestamp: entryTimestamp,
123
175
  });
124
176
  }
125
177
 
126
178
  const toolResults = parts.filter((p) => p.type === 'tool_result');
127
179
  if (toolResults.length > 0) {
128
180
  messages.push({
129
- id: `tool-result-${entry.uuid || messageIndex}`,
181
+ id: `tool-result-${entryUuid || messageIndex}`,
130
182
  parts: toolResults,
131
183
  role: 'system',
132
- timestamp: entry.timestamp || '',
184
+ timestamp: entryTimestamp,
133
185
  });
134
186
  }
135
187
  } else if (entryType === 'assistant') {
136
- const msg = entry.message;
188
+ const msg = isRecord(entry.message) ? entry.message : null;
137
189
  if (!msg?.content) {
138
190
  return { assistantCompleted, messages };
139
191
  }
140
192
 
141
- const content = Array.isArray(msg.content) ? msg.content : [msg.content];
142
- const msgId = msg.id || entry.uuid;
193
+ const blocks = toContentBlocks(msg.content);
194
+ const msgId = str(msg, 'id') || entryUuid;
143
195
 
144
- for (const block of content) {
196
+ for (const block of blocks) {
145
197
  const part = parseAssistantBlock(block);
146
198
  if (!part) {
147
199
  continue;
148
200
  }
149
201
 
150
202
  if (!assistantTurns.has(msgId)) {
151
- assistantTurns.set(msgId, { parts: [], timestamp: entry.timestamp || '' });
203
+ assistantTurns.set(msgId, { parts: [], timestamp: entryTimestamp });
204
+ }
205
+ const turn = assistantTurns.get(msgId);
206
+ if (turn) {
207
+ turn.parts.push(part);
152
208
  }
153
- assistantTurns.get(msgId)!.parts.push(part);
154
209
  }
155
210
 
156
211
  if (msg.stop_reason) {
@@ -1,11 +1,70 @@
1
+ import type { ConversationMessage, MessagePart, ProjectGroup, SessionInfo } from '$lib/types';
2
+
1
3
  import * as crypto from 'crypto';
2
4
  import * as fs from 'fs';
3
5
  import * as path from 'path';
4
6
 
5
- import type { ConversationMessage, MessagePart, ProjectGroup, SessionInfo } from './types';
6
-
7
7
  import { parseJsonlText } from './jsonl-parser';
8
8
 
9
+ const SYSTEM_TAG_PREFIXES = [
10
+ '<local-command',
11
+ '<command-name>',
12
+ '<command-message>',
13
+ '<command-args>',
14
+ '<local-command-stdout>',
15
+ '<local-command-caveat>',
16
+ '<system-reminder>',
17
+ '<task-notification>',
18
+ ];
19
+
20
+ /** Extract plain text from message content (string or array of content blocks). */
21
+ function extractContentText(content: unknown): string {
22
+ if (typeof content === 'string') {
23
+ return content.trim();
24
+ }
25
+ if (Array.isArray(content)) {
26
+ for (const b of content) {
27
+ if (typeof b === 'string' && b.trim()) {
28
+ return b.trim();
29
+ }
30
+ if (typeof b === 'object' && b !== null) {
31
+ const block = b as Record<string, unknown>;
32
+ if (block.type === 'text' && typeof block.text === 'string' && block.text.trim()) {
33
+ return block.text.trim();
34
+ }
35
+ }
36
+ }
37
+ }
38
+ return '';
39
+ }
40
+
41
+ /** Find the first real user prompt from raw JSONL content. */
42
+ function findFirstUserPrompt(content: string): string {
43
+ for (const line of content.split('\n')) {
44
+ if (!line.trim()) {
45
+ continue;
46
+ }
47
+ try {
48
+ const entry = JSON.parse(line) as Record<string, unknown>;
49
+ if (entry.type !== 'user') {
50
+ continue;
51
+ }
52
+ const msg = entry.message as Record<string, unknown> | undefined;
53
+ if (!msg?.content) {
54
+ continue;
55
+ }
56
+ const text = extractContentText(msg.content as unknown);
57
+ if (!text || SYSTEM_TAG_PREFIXES.some((p) => text.startsWith(p))) {
58
+ continue;
59
+ }
60
+ return text;
61
+ } catch {
62
+ continue;
63
+ }
64
+ }
65
+ return '';
66
+ }
67
+
9
68
  // Short hash for project IDs (8 chars from SHA-256)
10
69
  function shortHash(input: string): string {
11
70
  return crypto.createHash('sha256').update(input).digest('hex').slice(0, 8);
@@ -235,67 +294,17 @@ function listSessionsForProject(projectDir: string): SessionInfo[] {
235
294
  const nl = content.indexOf('\n', countPos);
236
295
  const lineEnd = nl === -1 ? content.length : nl;
237
296
  const line = content.substring(countPos, lineEnd);
238
- if (line.includes('"type":"user"') || line.includes('"type":"assistant"')) {messageCount++;}
239
- if (nl === -1) {break;}
240
- countPos = nl + 1;
241
- }
242
- // Find the first real user message (skip system caveats, commands, tool results)
243
- const lines = content.split('\n');
244
- for (const line of lines) {
245
- if (!line.trim()) {
246
- continue;
297
+ if (line.includes('"type":"user"') || line.includes('"type":"assistant"')) {
298
+ messageCount++;
247
299
  }
248
- try {
249
- const entry = JSON.parse(line);
250
- if (entry.type !== 'user') {
251
- continue;
252
- }
253
- const msg = entry.message;
254
- if (!msg?.content) {
255
- continue;
256
- }
257
-
258
- // Extract text from content (can be string or array of blocks)
259
- let text = '';
260
- if (typeof msg.content === 'string') {
261
- text = msg.content.trim();
262
- } else if (Array.isArray(msg.content)) {
263
- for (const b of msg.content) {
264
- if (typeof b === 'string' && b.trim()) {
265
- text = b.trim();
266
- break;
267
- }
268
- if (typeof b === 'object' && b !== null && b.type === 'text' && b.text?.trim()) {
269
- text = b.text.trim();
270
- break;
271
- }
272
- }
273
- }
274
-
275
- if (!text) {
276
- continue;
277
- }
278
-
279
- // Skip system-injected caveats and command outputs
280
- // Keep aligned with cleanTitle() tag stripping
281
- if (
282
- text.startsWith('<local-command') ||
283
- text.startsWith('<command-name>') ||
284
- text.startsWith('<command-message>') ||
285
- text.startsWith('<command-args>') ||
286
- text.startsWith('<local-command-stdout>') ||
287
- text.startsWith('<local-command-caveat>') ||
288
- text.startsWith('<system-reminder>') ||
289
- text.startsWith('<task-notification>')
290
- ) {
291
- continue;
292
- }
293
-
294
- firstPrompt = text;
300
+ if (nl === -1) {
295
301
  break;
296
- } catch {
297
- continue;
298
302
  }
303
+ countPos = nl + 1;
304
+ }
305
+ const prompt = findFirstUserPrompt(content);
306
+ if (prompt) {
307
+ firstPrompt = prompt;
299
308
  }
300
309
  } catch {
301
310
  // ignore read errors
@@ -6,7 +6,7 @@ function shortHash(input: string): string {
6
6
  return crypto.createHash('sha256').update(input).digest('hex').slice(0, 8);
7
7
  }
8
8
 
9
- import type { ConversationMessage, MessagePart, ProjectGroup, SessionInfo } from './types';
9
+ import type { ConversationMessage, MessagePart, ProjectGroup, SessionInfo } from '$lib/types';
10
10
 
11
11
  import { resolveOpenCodeDbPath } from './opencode-db-path';
12
12
 
@@ -1,30 +1,12 @@
1
- import { readdirSync, readFileSync } from 'fs';
1
+ import type { ClaudeSessionFile, DetectedProcess } from '$lib/types';
2
+
3
+ import { resolveOpenCodeDbPath } from '$lib/modules/server/sessions/opencode-db-path';
4
+ import Database from 'better-sqlite3';
5
+ import { execSync } from 'child_process';
6
+ import { existsSync, readdirSync, readFileSync } from 'fs';
2
7
  import { homedir } from 'os';
3
8
  import { join } from 'path';
4
9
 
5
- // ---------------------------------------------------------------------------
6
- // Types
7
- // ---------------------------------------------------------------------------
8
-
9
- export interface DetectedProcess {
10
- command: 'claude' | 'opencode';
11
- cwd: string;
12
- kind: string;
13
- pid: number;
14
- projectPath: string;
15
- sessionId: string;
16
- startedAt: number;
17
- }
18
-
19
- interface ClaudeSessionFile {
20
- cwd: string;
21
- entrypoint: string;
22
- kind: string;
23
- pid: number;
24
- sessionId: string;
25
- startedAt: number;
26
- }
27
-
28
10
  // ---------------------------------------------------------------------------
29
11
  // Helpers
30
12
  // ---------------------------------------------------------------------------
@@ -34,6 +16,16 @@ function cwdToProjectPath(cwd: string): string {
34
16
  return cwd.replace(/\//g, '-');
35
17
  }
36
18
 
19
+ /** Check if any `opencode` process is currently running. */
20
+ function isOpenCodeRunning(): boolean {
21
+ try {
22
+ execSync('pgrep -x opencode', { stdio: 'ignore' });
23
+ return true;
24
+ } catch {
25
+ return false;
26
+ }
27
+ }
28
+
37
29
  /** Check if a process with the given PID is alive. */
38
30
  function isProcessAlive(pid: number): boolean {
39
31
  try {
@@ -50,12 +42,12 @@ function isProcessAlive(pid: number): boolean {
50
42
 
51
43
  const CLAUDE_SESSIONS_DIR = join(homedir(), '.claude', 'sessions');
52
44
 
45
+ // OpenCode sessions updated within this window are considered "live"
46
+ const OPENCODE_ACTIVE_THRESHOLD_MS = 3 * 60_000; // 3 minutes
47
+
53
48
  /**
54
- * Scan ~/.claude/sessions/*.json to find running Claude Code processes.
55
- * Each file is named <PID>.json and contains:
56
- * { pid, sessionId, cwd, startedAt, kind, entrypoint }
57
- *
58
- * For each file we verify the PID is still alive via process.kill(pid, 0).
49
+ * Scan ~/.claude/sessions/*.json to find running Claude Code processes,
50
+ * and query the OpenCode SQLite DB for recently active sessions.
59
51
  */
60
52
  export function detectRunningAISessions(): DetectedProcess[] {
61
53
  const results: DetectedProcess[] = [];
@@ -94,10 +86,59 @@ export function detectRunningAISessions(): DetectedProcess[] {
94
86
  // ~/.claude/sessions/ may not exist — that's fine
95
87
  }
96
88
 
89
+ // --- OpenCode sessions ---
90
+ // Only query the DB if an opencode process is actually running.
91
+ if (isOpenCodeRunning()) {
92
+ try {
93
+ const dbPath = resolveOpenCodeDbPath();
94
+ if (existsSync(dbPath)) {
95
+ const db = new Database(dbPath, { readonly: true });
96
+ try {
97
+ const cutoff = Date.now() - OPENCODE_ACTIVE_THRESHOLD_MS;
98
+ const cutoffSec = Math.floor(cutoff / 1000);
99
+
100
+ const rows = db
101
+ .prepare(
102
+ `SELECT id, directory, time_created, time_updated
103
+ FROM session
104
+ WHERE (time_archived IS NULL OR time_archived = 0)
105
+ AND (
106
+ (time_updated >= 1e12 AND time_updated > ?)
107
+ OR (time_updated < 1e12 AND time_updated > ?)
108
+ )
109
+ ORDER BY time_updated DESC
110
+ LIMIT 20`
111
+ )
112
+ .all(cutoff, cutoffSec) as {
113
+ directory: string;
114
+ id: string;
115
+ time_created: number;
116
+ time_updated: number;
117
+ }[];
118
+
119
+ for (const row of rows) {
120
+ const startMs = row.time_created >= 1e12 ? row.time_created : row.time_created * 1000;
121
+ results.push({
122
+ command: 'opencode',
123
+ cwd: row.directory || '',
124
+ kind: 'interactive',
125
+ pid: 0, // OpenCode doesn't expose per-session PIDs
126
+ projectPath: cwdToProjectPath(row.directory || ''),
127
+ sessionId: row.id,
128
+ startedAt: startMs,
129
+ });
130
+ }
131
+ } finally {
132
+ db.close();
133
+ }
134
+ }
135
+ } catch {
136
+ // OpenCode DB missing or unreadable — skip silently
137
+ }
138
+ }
139
+
97
140
  // Sort by startedAt descending (most recent first)
98
141
  results.sort((a, b) => b.startedAt - a.startedAt);
99
142
 
100
- // TODO: Add OpenCode process detection (check running opencode processes or query SQLite DB)
101
-
102
143
  return results;
103
144
  }
@@ -1,42 +1,2 @@
1
- // Re-export generated types that match 1:1
2
- export type { MessageRole, ProjectGroup, SessionInfo } from '$generated/types';
3
- import type { MessageRole } from '$generated/types';
4
-
5
- // ── Local interfaces ─────────────────────────────────────────────────
6
- // These remain local because the generated versions differ structurally:
7
- // generated MessagePart uses wrapper classes (CMessagePartTextPart, etc.)
8
- // and part types use `type: string` instead of string literals needed
9
- // for discriminated unions. Declared as interfaces per ESLint rules.
10
-
11
- export interface ConversationMessage {
12
- id: string;
13
- parts: MessagePart[];
14
- role: MessageRole;
15
- timestamp: string;
16
- }
17
-
18
- export type MessagePart = TextPart | ThinkingPart | ToolResultPart | ToolUsePart;
19
-
20
- export interface TextPart {
21
- content: string;
22
- type: 'text';
23
- }
24
-
25
- export interface ThinkingPart {
26
- content: string;
27
- type: 'thinking';
28
- }
29
-
30
- export interface ToolResultPart {
31
- isError: boolean;
32
- output: string;
33
- toolUseId: string;
34
- type: 'tool_result';
35
- }
36
-
37
- export interface ToolUsePart {
38
- id: string;
39
- input: Record<string, unknown>;
40
- toolName: string;
41
- type: 'tool_use';
42
- }
1
+ // All session types have been moved to $lib/types/sessions.ts.
2
+ // Import from '$lib/types' instead of this file.
@@ -7,33 +7,14 @@
7
7
  * so PtyManager can slot it in as `ManagedTerminal.pty`.
8
8
  */
9
9
 
10
- import type { ConnectResult } from '$generated/types';
10
+ import type {
11
+ ConnectResult,
12
+ HolderIncomingMessage as IncomingMessage,
13
+ HolderOutgoingMessage as OutgoingMessage,
14
+ } from '$lib/types';
11
15
 
12
16
  import * as net from 'net';
13
17
 
14
- // ── Local Protocol Types ──────────────────────────────────────────────
15
- // The generated union types (IncomingMessage, OutgoingMessage) use
16
- // class wrappers and non-literal discriminants, making them hard to
17
- // narrow with switch/case. We keep simple local types matching the
18
- // ndjson protocol from the design spec for runtime dispatch.
19
-
20
- /** Messages received from the holder process. */
21
- type IncomingMessage =
22
- | { active: boolean; type: 'activity' }
23
- | { code: null | number; signal: null | string; type: 'exit' }
24
- | { data: string; type: 'output' }
25
- | { data: string; type: 'scrollback' }
26
- | { exitCode: null | number; exited: boolean; pid: number; type: 'info' }
27
- | { path: string; type: 'cwd' };
28
-
29
- // ── Connect Result ────────────────────────────────────────────────────
30
-
31
- /** Messages sent to the holder process. */
32
- type OutgoingMessage =
33
- | { cols: number; rows: number; type: 'resize' }
34
- | { data: string; type: 'input' }
35
- | { signal?: string; type: 'kill' };
36
-
37
18
  // ── HolderClient ──────────────────────────────────────────────────────
38
19
 
39
20
  export class HolderClient {
@@ -92,7 +73,7 @@ export class HolderClient {
92
73
  const lines = this.lineBuf.split('\n');
93
74
  // Keep the last element — it is either empty (complete line)
94
75
  // or a partial line still being received.
95
- this.lineBuf = lines.pop()!;
76
+ this.lineBuf = lines.pop() ?? '';
96
77
 
97
78
  for (const line of lines) {
98
79
  if (line.length === 0) {
@@ -101,11 +82,6 @@ export class HolderClient {
101
82
 
102
83
  let msg: IncomingMessage;
103
84
  try {
104
- // TODO: Apply generated holder decoders (decodeHolderClientMessage)
105
- // at this socket boundary once the generated union discriminant
106
- // types support literal narrowing with switch/case. Currently the
107
- // generated wrappers use non-literal discriminants, so we keep
108
- // local IncomingMessage types for runtime dispatch.
109
85
  msg = JSON.parse(line) as IncomingMessage;
110
86
  } catch {
111
87
  continue;
@@ -126,16 +102,16 @@ export class HolderClient {
126
102
 
127
103
  // Handshake complete once we have info.
128
104
  if (info !== null) {
129
- const settle = () => {
130
- if (settled) {
105
+ const settle = (): void => {
106
+ if (settled || !info) {
131
107
  return;
132
108
  }
133
109
  settled = true;
134
110
  clearTimeout(handshakeTimer);
135
111
  resolve({
136
- exitCode: info!.exitCode,
137
- exited: info!.exited,
138
- pid: info!.pid,
112
+ exitCode: info.exitCode,
113
+ exited: info.exited,
114
+ pid: info.pid,
139
115
  scrollback,
140
116
  });
141
117
  // Replay queued messages in the next macrotask so that