@juspay/shooter 1.5.0 → 1.6.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (478) hide show
  1. package/README.md +24 -20
  2. package/bin/shooter.cjs +68 -17
  3. package/build/client/_app/immutable/assets/2.Dk9NfqnS.css +1 -0
  4. package/build/client/_app/immutable/assets/2.Dk9NfqnS.css.br +0 -0
  5. package/build/client/_app/immutable/assets/2.Dk9NfqnS.css.gz +0 -0
  6. package/build/client/_app/immutable/assets/3.DHxQoulp.css +1 -0
  7. package/build/client/_app/immutable/assets/3.DHxQoulp.css.br +0 -0
  8. package/build/client/_app/immutable/assets/3.DHxQoulp.css.gz +0 -0
  9. package/build/client/_app/immutable/assets/{3.DGDHCVnW.css → 4.D5l1JxgO.css} +1 -1
  10. package/build/client/_app/immutable/assets/4.D5l1JxgO.css.br +0 -0
  11. package/build/client/_app/immutable/assets/4.D5l1JxgO.css.gz +0 -0
  12. package/build/client/_app/immutable/assets/5.C5qz-NeI.css +1 -0
  13. package/build/client/_app/immutable/assets/5.C5qz-NeI.css.br +0 -0
  14. package/build/client/_app/immutable/assets/5.C5qz-NeI.css.gz +0 -0
  15. package/build/client/_app/immutable/chunks/1mEchsPO.js +1 -0
  16. package/build/client/_app/immutable/chunks/1mEchsPO.js.br +0 -0
  17. package/build/client/_app/immutable/chunks/1mEchsPO.js.gz +0 -0
  18. package/build/client/_app/immutable/chunks/B7X-vhXI.js +1 -0
  19. package/build/client/_app/immutable/chunks/B7X-vhXI.js.br +0 -0
  20. package/build/client/_app/immutable/chunks/B7X-vhXI.js.gz +0 -0
  21. package/build/client/_app/immutable/chunks/BRkqKgVG.js +1 -0
  22. package/build/client/_app/immutable/chunks/BRkqKgVG.js.br +0 -0
  23. package/build/client/_app/immutable/chunks/BRkqKgVG.js.gz +0 -0
  24. package/build/client/_app/immutable/chunks/BfJ-f-Tu.js +1 -0
  25. package/build/client/_app/immutable/chunks/BfJ-f-Tu.js.br +2 -0
  26. package/build/client/_app/immutable/chunks/BfJ-f-Tu.js.gz +0 -0
  27. package/build/client/_app/immutable/chunks/CGMJxf7r.js +1 -0
  28. package/build/client/_app/immutable/chunks/CGMJxf7r.js.br +0 -0
  29. package/build/client/_app/immutable/chunks/CGMJxf7r.js.gz +0 -0
  30. package/build/client/_app/immutable/chunks/{CZHsSL_X.js → CJFjKwJ7.js} +1 -1
  31. package/build/client/_app/immutable/chunks/CJFjKwJ7.js.br +0 -0
  32. package/build/client/_app/immutable/chunks/CJFjKwJ7.js.gz +0 -0
  33. package/build/client/_app/immutable/chunks/CNH2HlKj.js +20 -0
  34. package/build/client/_app/immutable/chunks/CNH2HlKj.js.br +0 -0
  35. package/build/client/_app/immutable/chunks/CNH2HlKj.js.gz +0 -0
  36. package/build/client/_app/immutable/chunks/CR6bkGJW.js +6 -0
  37. package/build/client/_app/immutable/chunks/CR6bkGJW.js.br +0 -0
  38. package/build/client/_app/immutable/chunks/CR6bkGJW.js.gz +0 -0
  39. package/build/client/_app/immutable/chunks/CVtJ6yRM.js +1 -0
  40. package/build/client/_app/immutable/chunks/CVtJ6yRM.js.br +0 -0
  41. package/build/client/_app/immutable/chunks/CVtJ6yRM.js.gz +0 -0
  42. package/build/client/_app/immutable/chunks/{CSoRdFvv.js → CaiJSUi3.js} +1 -1
  43. package/build/client/_app/immutable/chunks/CaiJSUi3.js.br +0 -0
  44. package/build/client/_app/immutable/chunks/CaiJSUi3.js.gz +0 -0
  45. package/build/client/_app/immutable/chunks/{DjsDGxCa.js → CmczWE_d.js} +4 -4
  46. package/build/client/_app/immutable/chunks/CmczWE_d.js.br +0 -0
  47. package/build/client/_app/immutable/chunks/CmczWE_d.js.gz +0 -0
  48. package/build/client/_app/immutable/chunks/CsgHjHGZ.js +1 -0
  49. package/build/client/_app/immutable/chunks/CsgHjHGZ.js.br +0 -0
  50. package/build/client/_app/immutable/chunks/CsgHjHGZ.js.gz +0 -0
  51. package/build/client/_app/immutable/chunks/{UJOiqIYE.js → CtrCjGZT.js} +1 -1
  52. package/build/client/_app/immutable/chunks/CtrCjGZT.js.br +0 -0
  53. package/build/client/_app/immutable/chunks/CtrCjGZT.js.gz +0 -0
  54. package/build/client/_app/immutable/chunks/DDiOVAd8.js +61 -0
  55. package/build/client/_app/immutable/chunks/DDiOVAd8.js.br +0 -0
  56. package/build/client/_app/immutable/chunks/DDiOVAd8.js.gz +0 -0
  57. package/build/client/_app/immutable/chunks/DVl0sebP.js +2 -0
  58. package/build/client/_app/immutable/chunks/DVl0sebP.js.br +0 -0
  59. package/build/client/_app/immutable/chunks/DVl0sebP.js.gz +0 -0
  60. package/build/client/_app/immutable/chunks/{CiF38mQq.js → Dc_Gg2H6.js} +1 -1
  61. package/build/client/_app/immutable/chunks/Dc_Gg2H6.js.br +0 -0
  62. package/build/client/_app/immutable/chunks/Dc_Gg2H6.js.gz +0 -0
  63. package/build/client/_app/immutable/chunks/{CRbaG9cv.js → DlnAjkg1.js} +1 -1
  64. package/build/client/_app/immutable/chunks/DlnAjkg1.js.br +0 -0
  65. package/build/client/_app/immutable/chunks/{CRbaG9cv.js.gz → DlnAjkg1.js.gz} +0 -0
  66. package/build/client/_app/immutable/chunks/YKoRJzXZ.js +3 -0
  67. package/build/client/_app/immutable/chunks/YKoRJzXZ.js.br +0 -0
  68. package/build/client/_app/immutable/chunks/YKoRJzXZ.js.gz +0 -0
  69. package/build/client/_app/immutable/chunks/gQJcRhou.js +1 -0
  70. package/build/client/_app/immutable/chunks/gQJcRhou.js.br +0 -0
  71. package/build/client/_app/immutable/chunks/gQJcRhou.js.gz +0 -0
  72. package/build/client/_app/immutable/chunks/pRcLbE0d.js +1 -0
  73. package/build/client/_app/immutable/chunks/pRcLbE0d.js.br +0 -0
  74. package/build/client/_app/immutable/chunks/pRcLbE0d.js.gz +0 -0
  75. package/build/client/_app/immutable/entry/app.CFPgQOa8.js +2 -0
  76. package/build/client/_app/immutable/entry/app.CFPgQOa8.js.br +0 -0
  77. package/build/client/_app/immutable/entry/app.CFPgQOa8.js.gz +0 -0
  78. package/build/client/_app/immutable/entry/start.BnJOVqhI.js +1 -0
  79. package/build/client/_app/immutable/entry/start.BnJOVqhI.js.br +2 -0
  80. package/build/client/_app/immutable/entry/start.BnJOVqhI.js.gz +0 -0
  81. package/build/client/_app/immutable/nodes/0.DR-BBF5r.js +1 -0
  82. package/build/client/_app/immutable/nodes/0.DR-BBF5r.js.br +0 -0
  83. package/build/client/_app/immutable/nodes/0.DR-BBF5r.js.gz +0 -0
  84. package/build/client/_app/immutable/nodes/1.CNm6rAwf.js +1 -0
  85. package/build/client/_app/immutable/nodes/1.CNm6rAwf.js.br +0 -0
  86. package/build/client/_app/immutable/nodes/1.CNm6rAwf.js.gz +0 -0
  87. package/build/client/_app/immutable/nodes/2.B08usYzr.js +13 -0
  88. package/build/client/_app/immutable/nodes/2.B08usYzr.js.br +0 -0
  89. package/build/client/_app/immutable/nodes/2.B08usYzr.js.gz +0 -0
  90. package/build/client/_app/immutable/nodes/3.CsY6J5HS.js +9 -0
  91. package/build/client/_app/immutable/nodes/3.CsY6J5HS.js.br +0 -0
  92. package/build/client/_app/immutable/nodes/3.CsY6J5HS.js.gz +0 -0
  93. package/build/client/_app/immutable/nodes/4.B_pbOZoD.js +4 -0
  94. package/build/client/_app/immutable/nodes/4.B_pbOZoD.js.br +0 -0
  95. package/build/client/_app/immutable/nodes/4.B_pbOZoD.js.gz +0 -0
  96. package/build/client/_app/immutable/nodes/5.CdLPNo5-.js +1 -0
  97. package/build/client/_app/immutable/nodes/5.CdLPNo5-.js.br +0 -0
  98. package/build/client/_app/immutable/nodes/5.CdLPNo5-.js.gz +0 -0
  99. package/build/client/_app/immutable/nodes/6.CbQQ3FtZ.js +1 -0
  100. package/build/client/_app/immutable/nodes/6.CbQQ3FtZ.js.br +0 -0
  101. package/build/client/_app/immutable/nodes/6.CbQQ3FtZ.js.gz +0 -0
  102. package/build/client/_app/immutable/nodes/{5.DIkXVP4q.js → 7.CCKgiNNk.js} +3 -3
  103. package/build/client/_app/immutable/nodes/7.CCKgiNNk.js.br +0 -0
  104. package/build/client/_app/immutable/nodes/7.CCKgiNNk.js.gz +0 -0
  105. package/build/client/_app/immutable/nodes/8.C7AaheUD.js +2 -0
  106. package/build/client/_app/immutable/nodes/8.C7AaheUD.js.br +0 -0
  107. package/build/client/_app/immutable/nodes/8.C7AaheUD.js.gz +0 -0
  108. package/build/client/_app/immutable/nodes/9.DfL9kMC4.js +2 -0
  109. package/build/client/_app/immutable/nodes/9.DfL9kMC4.js.br +0 -0
  110. package/build/client/_app/immutable/nodes/9.DfL9kMC4.js.gz +0 -0
  111. package/build/client/_app/version.json +1 -1
  112. package/build/client/_app/version.json.br +0 -0
  113. package/build/client/_app/version.json.gz +0 -0
  114. package/build/server/chunks/0-DC2VLooL.js +23 -0
  115. package/build/server/chunks/0-DC2VLooL.js.map +1 -0
  116. package/build/server/chunks/1-XJaf8Jvf.js +9 -0
  117. package/build/server/chunks/{1-D0N7vVhH.js.map → 1-XJaf8Jvf.js.map} +1 -1
  118. package/build/server/chunks/2-D4Cx-1QL.js +21 -0
  119. package/build/server/chunks/2-D4Cx-1QL.js.map +1 -0
  120. package/build/server/chunks/3-CVhIEP-u.js +21 -0
  121. package/build/server/chunks/3-CVhIEP-u.js.map +1 -0
  122. package/build/server/chunks/4-0UE_6Ep-.js +23 -0
  123. package/build/server/chunks/4-0UE_6Ep-.js.map +1 -0
  124. package/build/server/chunks/5-BBIP1PzX.js +24 -0
  125. package/build/server/chunks/5-BBIP1PzX.js.map +1 -0
  126. package/build/server/chunks/6-QFSbzRMP.js +9 -0
  127. package/build/server/chunks/6-QFSbzRMP.js.map +1 -0
  128. package/build/server/chunks/7-CZ_YGjMV.js +9 -0
  129. package/build/server/chunks/7-CZ_YGjMV.js.map +1 -0
  130. package/build/server/chunks/8-Xe2Rugb4.js +9 -0
  131. package/build/server/chunks/8-Xe2Rugb4.js.map +1 -0
  132. package/build/server/chunks/9-IwHpC4SO.js +9 -0
  133. package/build/server/chunks/9-IwHpC4SO.js.map +1 -0
  134. package/build/server/chunks/{Button-Cs1aE6ka.js → Button-WKgiLWZI.js} +4 -9
  135. package/build/server/chunks/Button-WKgiLWZI.js.map +1 -0
  136. package/build/server/chunks/{EmptyState-DDFH1K8g.js → EmptyState-BUBqASsp.js} +3 -3
  137. package/build/server/chunks/{EmptyState-DDFH1K8g.js.map → EmptyState-BUBqASsp.js.map} +1 -1
  138. package/build/server/chunks/{Icon-CEUrotA6.js → Icon-BNBAg85a.js} +3 -3
  139. package/build/server/chunks/Icon-BNBAg85a.js.map +1 -0
  140. package/build/server/chunks/{Shimmer-DB8W1zt6.js → Shimmer-C4uBVwxz.js} +2 -2
  141. package/build/server/chunks/{Shimmer-DB8W1zt6.js.map → Shimmer-C4uBVwxz.js.map} +1 -1
  142. package/build/server/chunks/{_error.svelte-uCOJNxvr.js → _error.svelte-DkIwmECt.js} +5 -5
  143. package/build/server/chunks/{_error.svelte-uCOJNxvr.js.map → _error.svelte-DkIwmECt.js.map} +1 -1
  144. package/build/server/chunks/{_layout.svelte-CtWmEJwe.js → _layout.svelte-DllETxmJ.js} +13 -7
  145. package/build/server/chunks/_layout.svelte-DllETxmJ.js.map +1 -0
  146. package/build/server/chunks/_page.svelte-BZSdLKE_.js +118 -0
  147. package/build/server/chunks/_page.svelte-BZSdLKE_.js.map +1 -0
  148. package/build/server/chunks/{_page.svelte-CxWcQ0Am.js → _page.svelte-Cmuco1mC.js} +84 -199
  149. package/build/server/chunks/_page.svelte-Cmuco1mC.js.map +1 -0
  150. package/build/server/chunks/{_page.svelte-BgevQjq1.js → _page.svelte-Co5sF7W-.js} +12 -11
  151. package/build/server/chunks/{_page.svelte-BgevQjq1.js.map → _page.svelte-Co5sF7W-.js.map} +1 -1
  152. package/build/server/chunks/{_page.svelte-DO4oa_LY.js → _page.svelte-CpL3R-VI.js} +8 -8
  153. package/build/server/chunks/{_page.svelte-DO4oa_LY.js.map → _page.svelte-CpL3R-VI.js.map} +1 -1
  154. package/build/server/chunks/_page.svelte-DDSzYLUs.js +137 -0
  155. package/build/server/chunks/_page.svelte-DDSzYLUs.js.map +1 -0
  156. package/build/server/chunks/_page.svelte-JIkgFUFf.js +26 -0
  157. package/build/server/chunks/_page.svelte-JIkgFUFf.js.map +1 -0
  158. package/build/server/chunks/{_page.svelte-CVq6tRb3.js → _page.svelte-Y9-O5a5w.js} +10 -9
  159. package/build/server/chunks/_page.svelte-Y9-O5a5w.js.map +1 -0
  160. package/build/server/chunks/{_page.svelte-BcZaKdX9.js → _page.svelte-fcX09N4d.js} +9 -9
  161. package/build/server/chunks/{_page.svelte-BcZaKdX9.js.map → _page.svelte-fcX09N4d.js.map} +1 -1
  162. package/build/server/chunks/{_server.ts-DYpJImqd.js → _server.ts-0Xr2fWaq.js} +9 -5
  163. package/build/server/chunks/_server.ts-0Xr2fWaq.js.map +1 -0
  164. package/build/server/chunks/{_server.ts-CTpcLUH8.js → _server.ts-2ixC-X3K.js} +20 -5
  165. package/build/server/chunks/_server.ts-2ixC-X3K.js.map +1 -0
  166. package/build/server/chunks/{_server.ts-CAxsWKvS.js → _server.ts-40c_epk8.js} +20 -4
  167. package/build/server/chunks/_server.ts-40c_epk8.js.map +1 -0
  168. package/build/server/chunks/{_server.ts-WhTJBEJy.js → _server.ts-A9_tRR-K.js} +5 -4
  169. package/build/server/chunks/{_server.ts-WhTJBEJy.js.map → _server.ts-A9_tRR-K.js.map} +1 -1
  170. package/build/server/chunks/_server.ts-BRAzC6W1.js +98 -0
  171. package/build/server/chunks/_server.ts-BRAzC6W1.js.map +1 -0
  172. package/build/server/chunks/{_server.ts-DB_Kg97c.js → _server.ts-BScvgttw.js} +24 -4
  173. package/build/server/chunks/_server.ts-BScvgttw.js.map +1 -0
  174. package/build/server/chunks/{_server.ts-tSpgyl1D.js → _server.ts-Bjbr7glm.js} +4 -3
  175. package/build/server/chunks/_server.ts-Bjbr7glm.js.map +1 -0
  176. package/build/server/chunks/{_server.ts-COu0vNpd.js → _server.ts-BrqaMMAa.js} +7 -6
  177. package/build/server/chunks/_server.ts-BrqaMMAa.js.map +1 -0
  178. package/build/server/chunks/{_server.ts-vekTmWAx.js → _server.ts-BuYyCrnF.js} +6 -4
  179. package/build/server/chunks/_server.ts-BuYyCrnF.js.map +1 -0
  180. package/build/server/chunks/{_server.ts-DYvb9ijZ.js → _server.ts-ByPExYfO.js} +4 -3
  181. package/build/server/chunks/{_server.ts-DYvb9ijZ.js.map → _server.ts-ByPExYfO.js.map} +1 -1
  182. package/build/server/chunks/_server.ts-CjpQ10xh.js +123 -0
  183. package/build/server/chunks/_server.ts-CjpQ10xh.js.map +1 -0
  184. package/build/server/chunks/_server.ts-CyjDrcZN.js +21 -0
  185. package/build/server/chunks/_server.ts-CyjDrcZN.js.map +1 -0
  186. package/build/server/chunks/{_server.ts-DV8zTCF9.js → _server.ts-DOGUMzPx.js} +4 -3
  187. package/build/server/chunks/{_server.ts-DV8zTCF9.js.map → _server.ts-DOGUMzPx.js.map} +1 -1
  188. package/build/server/chunks/_server.ts-DZvfyuNj.js +15 -0
  189. package/build/server/chunks/_server.ts-DZvfyuNj.js.map +1 -0
  190. package/build/server/chunks/{_server.ts-XzT2UHM1.js → _server.ts-DkPPTUPo.js} +4 -3
  191. package/build/server/chunks/{_server.ts-XzT2UHM1.js.map → _server.ts-DkPPTUPo.js.map} +1 -1
  192. package/build/server/chunks/{_server.ts-Deok2y88.js → _server.ts-Ds_SUGC3.js} +184 -90
  193. package/build/server/chunks/_server.ts-Ds_SUGC3.js.map +1 -0
  194. package/build/server/chunks/{_server.ts-Ch-6iOHp.js → _server.ts-G8OeADGj.js} +141 -89
  195. package/build/server/chunks/_server.ts-G8OeADGj.js.map +1 -0
  196. package/build/server/chunks/{auth-DeCdZ83n.js → auth-DuunT7Cg.js} +2 -2
  197. package/build/server/chunks/{auth-DeCdZ83n.js.map → auth-DuunT7Cg.js.map} +1 -1
  198. package/build/server/chunks/{client-BdGHe_hY.js → client-DRtPDkMh.js} +4 -4
  199. package/build/server/chunks/{client-BdGHe_hY.js.map → client-DRtPDkMh.js.map} +1 -1
  200. package/build/server/chunks/client2-bqqmu0b7.js +7 -0
  201. package/build/server/chunks/{client2-CCBGA-2V.js.map → client2-bqqmu0b7.js.map} +1 -1
  202. package/build/server/chunks/close-BGlLztTb.js +192 -0
  203. package/build/server/chunks/close-BGlLztTb.js.map +1 -0
  204. package/build/server/chunks/events-handler-Dm1mNPQP.js +20 -0
  205. package/build/server/chunks/events-handler-Dm1mNPQP.js.map +1 -0
  206. package/build/server/chunks/html-FW6Ia4bL.js +8 -0
  207. package/build/server/chunks/html-FW6Ia4bL.js.map +1 -0
  208. package/build/server/chunks/{shared-server-sSGG17Df.js → index-CoD1IJuy.js} +2 -11
  209. package/build/server/chunks/index-CoD1IJuy.js.map +1 -0
  210. package/build/server/chunks/{index-DwaY1cAm.js → index-DP9bWJrR.js} +2 -2
  211. package/build/server/chunks/{index-DwaY1cAm.js.map → index-DP9bWJrR.js.map} +1 -1
  212. package/build/server/chunks/{index-server-CrDaL06Y.js → index-server-BUmV4MIG.js} +2 -2
  213. package/build/server/chunks/index-server-BUmV4MIG.js.map +1 -0
  214. package/build/server/chunks/index-server2-BJrT0wnA.js +5 -0
  215. package/build/server/chunks/index-server2-BJrT0wnA.js.map +1 -0
  216. package/build/server/chunks/{index2-CgclKpUj.js → index2-D5Y19GKR.js} +2 -2
  217. package/build/server/chunks/index2-D5Y19GKR.js.map +1 -0
  218. package/build/server/chunks/{library-apns-BqJbvSKh.js → library-apns-Cf-E-DhM.js} +5 -2
  219. package/build/server/chunks/library-apns-Cf-E-DhM.js.map +1 -0
  220. package/build/server/chunks/providers-DtstoHQ0.js +17 -0
  221. package/build/server/chunks/providers-DtstoHQ0.js.map +1 -0
  222. package/build/server/chunks/{pty-manager-BQVB7IVj.js → pty-manager-TyMUpDA9.js} +41 -9
  223. package/build/server/chunks/pty-manager-TyMUpDA9.js.map +1 -0
  224. package/build/server/chunks/{root-DDSnEAZv.js → root-CATOR_0t.js} +2 -2
  225. package/build/server/chunks/root-CATOR_0t.js.map +1 -0
  226. package/build/server/chunks/shared-server-DaWdgxVh.js +11 -0
  227. package/build/server/chunks/shared-server-DaWdgxVh.js.map +1 -0
  228. package/build/server/chunks/{state.svelte-hBbXlUak.js → state.svelte-CftllyvC.js} +3 -3
  229. package/build/server/chunks/state.svelte-CftllyvC.js.map +1 -0
  230. package/build/server/chunks/{stores-DHNzYNpX.js → stores-BjL57aOK.js} +4 -4
  231. package/build/server/chunks/{stores-DHNzYNpX.js.map → stores-BjL57aOK.js.map} +1 -1
  232. package/build/server/index.js +173 -6
  233. package/build/server/index.js.map +1 -1
  234. package/build/server/manifest.js +53 -30
  235. package/build/server/manifest.js.map +1 -1
  236. package/package.json +24 -6
  237. package/scripts/dev.mjs +361 -0
  238. package/scripts/install.sh +11 -3
  239. package/scripts/{fix-generated-types.sh → postgen-types.sh} +2 -2
  240. package/scripts/setup.cjs +219 -24
  241. package/scripts/vercel-env-commands.sh +3 -3
  242. package/server.ts +3 -3
  243. package/src/app.html +163 -0
  244. package/src/lib/modules/client/activity/ActivityFeed.svelte +279 -0
  245. package/src/lib/modules/client/activity/index.ts +8 -0
  246. package/src/lib/modules/client/activity/store.svelte.ts +478 -0
  247. package/src/lib/modules/client/activity/summarizer.ts +224 -0
  248. package/src/lib/modules/client/common/Card.svelte +2 -9
  249. package/src/lib/modules/client/common/EmptyState.svelte +2 -20
  250. package/src/lib/modules/client/common/Icon.svelte +3 -7
  251. package/src/lib/modules/client/common/StatusBadge.svelte +2 -4
  252. package/src/lib/modules/client/common/config-guard.ts +22 -2
  253. package/src/lib/modules/client/common/index.ts +1 -1
  254. package/src/lib/modules/client/common/time.ts +27 -9
  255. package/src/lib/modules/client/dashboard/DashboardCard.svelte +374 -0
  256. package/src/lib/modules/client/dashboard/DashboardView.svelte +66 -0
  257. package/src/lib/modules/client/dashboard/index.ts +12 -0
  258. package/src/lib/modules/client/dashboard/store.svelte.ts +663 -0
  259. package/src/lib/modules/client/dashboard/summarizer.ts +205 -0
  260. package/src/lib/modules/client/neurolink/fetch-proxy.ts +70 -0
  261. package/src/lib/modules/client/neurolink/provider-config.ts +111 -0
  262. package/src/lib/modules/client/terminal/ChatView.svelte +46 -43
  263. package/src/lib/modules/client/terminal/CommandPalette.svelte +3 -12
  264. package/src/lib/modules/client/terminal/ConnectionStatus.svelte +3 -6
  265. package/src/lib/modules/client/terminal/LaunchSheet.svelte +10 -21
  266. package/src/lib/modules/client/terminal/QuickKeys.svelte +4 -11
  267. package/src/lib/modules/client/terminal/ShortcutsHelp.svelte +3 -6
  268. package/src/lib/modules/client/terminal/keyboard-shortcuts.ts +5 -7
  269. package/src/lib/modules/client/terminal/xterm-wrapper.ts +27 -47
  270. package/src/lib/modules/server/apn/library-apns.ts +6 -3
  271. package/src/lib/modules/server/apn/notification-history.ts +2 -2
  272. package/src/lib/modules/server/apn/notification-sessions.ts +1 -3
  273. package/src/lib/modules/server/apn/pending-requests.ts +1 -1
  274. package/src/lib/modules/server/apn/types.ts +2 -52
  275. package/src/lib/modules/server/cli/index.ts +1 -30
  276. package/src/lib/modules/server/cli/runner.ts +7 -15
  277. package/src/lib/modules/server/fcm/fcm-service.ts +2 -2
  278. package/src/lib/modules/server/sessions/jsonl-parser.ts +97 -42
  279. package/src/lib/modules/server/sessions/jsonl-reader.ts +144 -76
  280. package/src/lib/modules/server/sessions/opencode-reader.ts +1 -1
  281. package/src/lib/modules/server/sessions/process-detector.ts +72 -31
  282. package/src/lib/modules/server/sessions/types.ts +2 -42
  283. package/src/lib/modules/server/terminal/holder-client.ts +11 -35
  284. package/src/lib/modules/server/terminal/opencode-watcher.ts +16 -24
  285. package/src/lib/modules/server/terminal/pty-manager.ts +40 -45
  286. package/src/lib/modules/server/terminal/session-watcher.ts +15 -17
  287. package/src/lib/modules/server/terminal/terminal-store.ts +1 -1
  288. package/src/lib/modules/server/ws/events-handler.ts +1 -16
  289. package/src/lib/modules/server/ws/keepalive.ts +1 -5
  290. package/src/lib/modules/server/ws/server.ts +1 -1
  291. package/src/lib/modules/server/ws/session-handler.ts +20 -86
  292. package/src/lib/modules/server/ws/terminal-handler.ts +28 -51
  293. package/src/lib/modules/server/ws/ticket-store.ts +1 -1
  294. package/src/lib/modules/shared/providers.ts +21 -0
  295. package/src/lib/types/activity.ts +18 -0
  296. package/src/lib/types/apn.ts +43 -0
  297. package/src/lib/types/cli.ts +39 -0
  298. package/src/lib/types/common.ts +39 -0
  299. package/src/lib/types/dashboard.ts +4 -0
  300. package/src/lib/types/generated/Client.ts +1656 -0
  301. package/src/{generated/types → lib/types/generated}/WsProtocol.ts +344 -2
  302. package/src/lib/types/index.ts +28 -0
  303. package/src/lib/types/neurolink.ts +4 -0
  304. package/src/lib/types/server.ts +93 -0
  305. package/src/lib/types/sessions.ts +59 -0
  306. package/src/lib/types/terminal-client.ts +132 -0
  307. package/src/lib/types/ws.ts +161 -0
  308. package/src/routes/+error.svelte +7 -2
  309. package/src/routes/+layout.server.ts +9 -0
  310. package/src/routes/+layout.svelte +36 -7
  311. package/src/routes/+page.server.ts +7 -0
  312. package/src/routes/+page.svelte +85 -35
  313. package/src/routes/activity/+page.server.ts +7 -0
  314. package/src/routes/activity/+page.svelte +58 -0
  315. package/src/routes/api/health/+server.ts +32 -19
  316. package/src/routes/api/neurolink-proxy/+server.ts +136 -0
  317. package/src/routes/api/notify/+server.ts +190 -87
  318. package/src/routes/api/sessions/+server.ts +1 -1
  319. package/src/routes/api/sessions/connect/+server.ts +10 -6
  320. package/src/routes/api/terminals/+server.ts +20 -1
  321. package/src/routes/api/terminals/[id]/+server.ts +16 -2
  322. package/src/routes/api/webhook/+server.ts +5 -33
  323. package/src/routes/api/ws-ticket/+server.ts +4 -4
  324. package/src/routes/config/+page.server.ts +9 -0
  325. package/src/routes/config/+page.svelte +118 -25
  326. package/src/routes/neurolink/+page.server.ts +10 -0
  327. package/src/routes/neurolink/+page.svelte +331 -0
  328. package/src/routes/project/+page.svelte +17 -12
  329. package/src/routes/session/[id]/+page.svelte +146 -62
  330. package/src/routes/terminals/+page.svelte +2 -2
  331. package/src/routes/terminals/[id]/+page.svelte +99 -88
  332. package/svelte.config.js +1 -3
  333. package/tsconfig.json +1 -0
  334. package/build/client/_app/immutable/assets/2.CAShZ7lQ.css +0 -1
  335. package/build/client/_app/immutable/assets/2.CAShZ7lQ.css.br +0 -1
  336. package/build/client/_app/immutable/assets/2.CAShZ7lQ.css.gz +0 -0
  337. package/build/client/_app/immutable/assets/3.DGDHCVnW.css.br +0 -0
  338. package/build/client/_app/immutable/assets/3.DGDHCVnW.css.gz +0 -0
  339. package/build/client/_app/immutable/chunks/B5NAKyil.js +0 -20
  340. package/build/client/_app/immutable/chunks/B5NAKyil.js.br +0 -0
  341. package/build/client/_app/immutable/chunks/B5NAKyil.js.gz +0 -0
  342. package/build/client/_app/immutable/chunks/B8XegpSE.js +0 -1
  343. package/build/client/_app/immutable/chunks/B8XegpSE.js.br +0 -0
  344. package/build/client/_app/immutable/chunks/B8XegpSE.js.gz +0 -0
  345. package/build/client/_app/immutable/chunks/B8zoBsv3.js +0 -6
  346. package/build/client/_app/immutable/chunks/B8zoBsv3.js.br +0 -0
  347. package/build/client/_app/immutable/chunks/B8zoBsv3.js.gz +0 -0
  348. package/build/client/_app/immutable/chunks/BIaXC2t9.js +0 -1
  349. package/build/client/_app/immutable/chunks/BIaXC2t9.js.br +0 -0
  350. package/build/client/_app/immutable/chunks/BIaXC2t9.js.gz +0 -0
  351. package/build/client/_app/immutable/chunks/BOYo8yTr.js +0 -1
  352. package/build/client/_app/immutable/chunks/BOYo8yTr.js.br +0 -0
  353. package/build/client/_app/immutable/chunks/BOYo8yTr.js.gz +0 -0
  354. package/build/client/_app/immutable/chunks/Bu1aqm5j.js +0 -1
  355. package/build/client/_app/immutable/chunks/Bu1aqm5j.js.br +0 -0
  356. package/build/client/_app/immutable/chunks/Bu1aqm5j.js.gz +0 -0
  357. package/build/client/_app/immutable/chunks/CQjSATpv.js +0 -61
  358. package/build/client/_app/immutable/chunks/CQjSATpv.js.br +0 -0
  359. package/build/client/_app/immutable/chunks/CQjSATpv.js.gz +0 -0
  360. package/build/client/_app/immutable/chunks/CRbaG9cv.js.br +0 -0
  361. package/build/client/_app/immutable/chunks/CSoRdFvv.js.br +0 -0
  362. package/build/client/_app/immutable/chunks/CSoRdFvv.js.gz +0 -0
  363. package/build/client/_app/immutable/chunks/CZHsSL_X.js.br +0 -0
  364. package/build/client/_app/immutable/chunks/CZHsSL_X.js.gz +0 -0
  365. package/build/client/_app/immutable/chunks/CiF38mQq.js.br +0 -0
  366. package/build/client/_app/immutable/chunks/CiF38mQq.js.gz +0 -0
  367. package/build/client/_app/immutable/chunks/DSU1n5N_.js +0 -1
  368. package/build/client/_app/immutable/chunks/DSU1n5N_.js.br +0 -0
  369. package/build/client/_app/immutable/chunks/DSU1n5N_.js.gz +0 -0
  370. package/build/client/_app/immutable/chunks/DVkn4r72.js +0 -1
  371. package/build/client/_app/immutable/chunks/DVkn4r72.js.br +0 -0
  372. package/build/client/_app/immutable/chunks/DVkn4r72.js.gz +0 -0
  373. package/build/client/_app/immutable/chunks/DjsDGxCa.js.br +0 -0
  374. package/build/client/_app/immutable/chunks/DjsDGxCa.js.gz +0 -0
  375. package/build/client/_app/immutable/chunks/UJOiqIYE.js.br +0 -0
  376. package/build/client/_app/immutable/chunks/UJOiqIYE.js.gz +0 -0
  377. package/build/client/_app/immutable/chunks/r0JawsZc.js +0 -2
  378. package/build/client/_app/immutable/chunks/r0JawsZc.js.br +0 -0
  379. package/build/client/_app/immutable/chunks/r0JawsZc.js.gz +0 -0
  380. package/build/client/_app/immutable/entry/app.CU7KVZja.js +0 -2
  381. package/build/client/_app/immutable/entry/app.CU7KVZja.js.br +0 -0
  382. package/build/client/_app/immutable/entry/app.CU7KVZja.js.gz +0 -0
  383. package/build/client/_app/immutable/entry/start.RAMZY19t.js +0 -1
  384. package/build/client/_app/immutable/entry/start.RAMZY19t.js.br +0 -2
  385. package/build/client/_app/immutable/entry/start.RAMZY19t.js.gz +0 -0
  386. package/build/client/_app/immutable/nodes/0.Bi3XYMSu.js +0 -1
  387. package/build/client/_app/immutable/nodes/0.Bi3XYMSu.js.br +0 -0
  388. package/build/client/_app/immutable/nodes/0.Bi3XYMSu.js.gz +0 -0
  389. package/build/client/_app/immutable/nodes/1.DTmfBFmm.js +0 -1
  390. package/build/client/_app/immutable/nodes/1.DTmfBFmm.js.br +0 -0
  391. package/build/client/_app/immutable/nodes/1.DTmfBFmm.js.gz +0 -0
  392. package/build/client/_app/immutable/nodes/2.Cm269yzt.js +0 -1
  393. package/build/client/_app/immutable/nodes/2.Cm269yzt.js.br +0 -0
  394. package/build/client/_app/immutable/nodes/2.Cm269yzt.js.gz +0 -0
  395. package/build/client/_app/immutable/nodes/3.3yohCM25.js +0 -3
  396. package/build/client/_app/immutable/nodes/3.3yohCM25.js.br +0 -0
  397. package/build/client/_app/immutable/nodes/3.3yohCM25.js.gz +0 -0
  398. package/build/client/_app/immutable/nodes/4.C25c5hMg.js +0 -1
  399. package/build/client/_app/immutable/nodes/4.C25c5hMg.js.br +0 -0
  400. package/build/client/_app/immutable/nodes/4.C25c5hMg.js.gz +0 -0
  401. package/build/client/_app/immutable/nodes/5.DIkXVP4q.js.br +0 -0
  402. package/build/client/_app/immutable/nodes/5.DIkXVP4q.js.gz +0 -0
  403. package/build/client/_app/immutable/nodes/6.BPL-HzUX.js +0 -2
  404. package/build/client/_app/immutable/nodes/6.BPL-HzUX.js.br +0 -0
  405. package/build/client/_app/immutable/nodes/6.BPL-HzUX.js.gz +0 -0
  406. package/build/client/_app/immutable/nodes/7.IgEqce53.js +0 -2
  407. package/build/client/_app/immutable/nodes/7.IgEqce53.js.br +0 -0
  408. package/build/client/_app/immutable/nodes/7.IgEqce53.js.gz +0 -0
  409. package/build/server/chunks/0-DiORznXb.js +0 -9
  410. package/build/server/chunks/0-DiORznXb.js.map +0 -1
  411. package/build/server/chunks/1-D0N7vVhH.js +0 -9
  412. package/build/server/chunks/2-DfSav7a7.js +0 -9
  413. package/build/server/chunks/2-DfSav7a7.js.map +0 -1
  414. package/build/server/chunks/3-Ck7ewhOX.js +0 -9
  415. package/build/server/chunks/3-Ck7ewhOX.js.map +0 -1
  416. package/build/server/chunks/4-DV5MZUz_.js +0 -9
  417. package/build/server/chunks/4-DV5MZUz_.js.map +0 -1
  418. package/build/server/chunks/5-DJhoAjb0.js +0 -9
  419. package/build/server/chunks/5-DJhoAjb0.js.map +0 -1
  420. package/build/server/chunks/6-Cp8CzYbr.js +0 -9
  421. package/build/server/chunks/6-Cp8CzYbr.js.map +0 -1
  422. package/build/server/chunks/7-BA4xzUj3.js +0 -9
  423. package/build/server/chunks/7-BA4xzUj3.js.map +0 -1
  424. package/build/server/chunks/Button-Cs1aE6ka.js.map +0 -1
  425. package/build/server/chunks/Icon-CEUrotA6.js.map +0 -1
  426. package/build/server/chunks/_layout.svelte-CtWmEJwe.js.map +0 -1
  427. package/build/server/chunks/_page.svelte-BdYynOck.js +0 -85
  428. package/build/server/chunks/_page.svelte-BdYynOck.js.map +0 -1
  429. package/build/server/chunks/_page.svelte-CVq6tRb3.js.map +0 -1
  430. package/build/server/chunks/_page.svelte-CxWcQ0Am.js.map +0 -1
  431. package/build/server/chunks/_server.ts-BStnNIcq.js +0 -34
  432. package/build/server/chunks/_server.ts-BStnNIcq.js.map +0 -1
  433. package/build/server/chunks/_server.ts-CAxsWKvS.js.map +0 -1
  434. package/build/server/chunks/_server.ts-COu0vNpd.js.map +0 -1
  435. package/build/server/chunks/_server.ts-CTpcLUH8.js.map +0 -1
  436. package/build/server/chunks/_server.ts-Cf84YIaW.js +0 -25
  437. package/build/server/chunks/_server.ts-Cf84YIaW.js.map +0 -1
  438. package/build/server/chunks/_server.ts-Ch-6iOHp.js.map +0 -1
  439. package/build/server/chunks/_server.ts-CtH0dhUp.js +0 -71
  440. package/build/server/chunks/_server.ts-CtH0dhUp.js.map +0 -1
  441. package/build/server/chunks/_server.ts-DB_Kg97c.js.map +0 -1
  442. package/build/server/chunks/_server.ts-DYpJImqd.js.map +0 -1
  443. package/build/server/chunks/_server.ts-Deok2y88.js.map +0 -1
  444. package/build/server/chunks/_server.ts-tSpgyl1D.js.map +0 -1
  445. package/build/server/chunks/_server.ts-vekTmWAx.js.map +0 -1
  446. package/build/server/chunks/client2-CCBGA-2V.js +0 -7
  447. package/build/server/chunks/index-server-CrDaL06Y.js.map +0 -1
  448. package/build/server/chunks/index2-CgclKpUj.js.map +0 -1
  449. package/build/server/chunks/library-apns-BqJbvSKh.js.map +0 -1
  450. package/build/server/chunks/pty-manager-BQVB7IVj.js.map +0 -1
  451. package/build/server/chunks/root-DDSnEAZv.js.map +0 -1
  452. package/build/server/chunks/shared-server-sSGG17Df.js.map +0 -1
  453. package/build/server/chunks/state.svelte-hBbXlUak.js.map +0 -1
  454. package/src/generated/types/Client.ts +0 -589
  455. package/src/lib/types/config.ts +0 -1
  456. /package/build/client/_app/immutable/assets/{4.BFUut--w.css → 6.BFUut--w.css} +0 -0
  457. /package/build/client/_app/immutable/assets/{4.BFUut--w.css.br → 6.BFUut--w.css.br} +0 -0
  458. /package/build/client/_app/immutable/assets/{4.BFUut--w.css.gz → 6.BFUut--w.css.gz} +0 -0
  459. /package/build/client/_app/immutable/assets/{5.BTOx7yt7.css → 7.BTOx7yt7.css} +0 -0
  460. /package/build/client/_app/immutable/assets/{5.BTOx7yt7.css.br → 7.BTOx7yt7.css.br} +0 -0
  461. /package/build/client/_app/immutable/assets/{5.BTOx7yt7.css.gz → 7.BTOx7yt7.css.gz} +0 -0
  462. /package/build/client/_app/immutable/assets/{6.eZGZN-BF.css → 8.eZGZN-BF.css} +0 -0
  463. /package/build/client/_app/immutable/assets/{6.eZGZN-BF.css.br → 8.eZGZN-BF.css.br} +0 -0
  464. /package/build/client/_app/immutable/assets/{6.eZGZN-BF.css.gz → 8.eZGZN-BF.css.gz} +0 -0
  465. /package/build/client/_app/immutable/assets/{7.DwS5ZHBh.css → 9.DwS5ZHBh.css} +0 -0
  466. /package/build/client/_app/immutable/assets/{7.DwS5ZHBh.css.br → 9.DwS5ZHBh.css.br} +0 -0
  467. /package/build/client/_app/immutable/assets/{7.DwS5ZHBh.css.gz → 9.DwS5ZHBh.css.gz} +0 -0
  468. /package/src/{generated/types → lib/types/generated}/API.ts +0 -0
  469. /package/src/{generated/types → lib/types/generated}/APN.ts +0 -0
  470. /package/src/{generated/types → lib/types/generated}/CLI.ts +0 -0
  471. /package/src/{generated/types → lib/types/generated}/Config.ts +0 -0
  472. /package/src/{generated/types → lib/types/generated}/Holder.ts +0 -0
  473. /package/src/{generated/types → lib/types/generated}/JWT.ts +0 -0
  474. /package/src/{generated/types → lib/types/generated}/Notification.ts +0 -0
  475. /package/src/{generated/types → lib/types/generated}/OpenCode.ts +0 -0
  476. /package/src/{generated/types → lib/types/generated}/Sessions.ts +0 -0
  477. /package/src/{generated/types → lib/types/generated}/Terminal.ts +0 -0
  478. /package/src/{generated/types → lib/types/generated}/index.ts +0 -0
@@ -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);
@@ -93,11 +152,13 @@ export function listProjectsWithSessions(): ProjectGroup[] {
93
152
  // Sort sessions by modified desc
94
153
  sessions.sort((a, b) => new Date(b.modified).getTime() - new Date(a.modified).getTime());
95
154
 
96
- // Prefer projectPath from session index, then cwd from JSONL, then decoded dir name
155
+ // Prefer projectPath from session index, then cwd from JSONL, then
156
+ // filesystem-validated decoder, then last-resort naive decoding.
97
157
  const realPath =
98
158
  sessions.find((s) => s.projectPath && !s.projectPath.includes('.claude/projects'))
99
159
  ?.projectPath ||
100
160
  readCwdFromProjectDir(projectDir, sessions) ||
161
+ decodeClaudeProjectDir(dir) ||
101
162
  (dir.startsWith('-') ? dir.replace(/-/g, '/') : `/${dir.replace(/-/g, '/')}`);
102
163
  const pathSegments = realPath.split('/').filter(Boolean);
103
164
  const projectName = pathSegments.slice(-2).join('/');
@@ -122,6 +183,10 @@ export function listSessions(): SessionInfo[] {
122
183
  return listSessionsForProject(projectDir);
123
184
  }
124
185
 
186
+ function bytesReadEnded(chunk: string): boolean {
187
+ return chunk.length > 0 && chunk.charCodeAt(chunk.length - 1) === 10;
188
+ }
189
+
125
190
  function cleanTitle(prompt: string): string {
126
191
  // Strip internal Claude Code XML markup tags, then remove ALL angle-bracket content.
127
192
  // Use a loop to handle nested/reconstructed tags (satisfies CodeQL multi-char sanitization).
@@ -157,6 +222,52 @@ function cleanTitle(prompt: string): string {
157
222
  return firstLine;
158
223
  }
159
224
 
225
+ /**
226
+ * Decode a Claude Code project directory name like "-home-parth-dogra-Desktop-Repo-pr-guardian"
227
+ * into the real filesystem path "/home/parth-dogra/Desktop/Repo/pr-guardian".
228
+ *
229
+ * Claude Code encodes paths by replacing "/" with "-", which is ambiguous when
230
+ * the original path contains hyphens (e.g. "parth-dogra", "pr-guardian"). This
231
+ * walks the filesystem from / and greedily matches the longest hyphen-joined
232
+ * segment that exists as a directory at each step.
233
+ *
234
+ * Returns null if no valid decoding exists on this filesystem.
235
+ */
236
+ function decodeClaudeProjectDir(encoded: string): null | string {
237
+ if (!encoded.startsWith('-')) {
238
+ return null;
239
+ }
240
+ const parts = encoded.slice(1).split('-');
241
+ if (parts.length === 0) {
242
+ return null;
243
+ }
244
+
245
+ let currentPath = '/';
246
+ let i = 0;
247
+ while (i < parts.length) {
248
+ let matchedTo = -1;
249
+ // Try the longest possible segment first (greedy longest match)
250
+ for (let j = parts.length; j > i; j--) {
251
+ const segment = parts.slice(i, j).join('-');
252
+ const candidate = path.join(currentPath, segment);
253
+ try {
254
+ if (fs.statSync(candidate).isDirectory()) {
255
+ matchedTo = j;
256
+ break;
257
+ }
258
+ } catch {
259
+ // not a directory / doesn't exist — try a shorter segment
260
+ }
261
+ }
262
+ if (matchedTo === -1) {
263
+ return null;
264
+ }
265
+ currentPath = path.join(currentPath, parts.slice(i, matchedTo).join('-'));
266
+ i = matchedTo;
267
+ }
268
+ return currentPath;
269
+ }
270
+
160
271
  function getProjectDir(): string {
161
272
  // Encode project path: /Users/sachinsharma/Developer/Personal/shooter -> -Users-sachinsharma-Developer-Personal-shooter
162
273
  const projectPath = process.cwd();
@@ -235,67 +346,17 @@ function listSessionsForProject(projectDir: string): SessionInfo[] {
235
346
  const nl = content.indexOf('\n', countPos);
236
347
  const lineEnd = nl === -1 ? content.length : nl;
237
348
  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;
349
+ if (line.includes('"type":"user"') || line.includes('"type":"assistant"')) {
350
+ messageCount++;
247
351
  }
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;
352
+ if (nl === -1) {
295
353
  break;
296
- } catch {
297
- continue;
298
354
  }
355
+ countPos = nl + 1;
356
+ }
357
+ const prompt = findFirstUserPrompt(content);
358
+ if (prompt) {
359
+ firstPrompt = prompt;
299
360
  }
300
361
  } catch {
301
362
  // ignore read errors
@@ -325,33 +386,40 @@ function listSessionsForProject(projectDir: string): SessionInfo[] {
325
386
  }
326
387
 
327
388
  function readCwdFromProjectDir(projectDir: string, sessions: SessionInfo[]): string {
389
+ // Scan complete JSONL lines until we find one with cwd. Newer Claude Code
390
+ // versions write metadata lines (permission-mode, file-history-snapshot)
391
+ // first, so cwd only appears on line 2+.
392
+ const READ_BYTES = 65536;
328
393
  for (const session of sessions) {
329
394
  try {
330
395
  const filePath = path.join(projectDir, `${session.id}.jsonl`);
331
396
  if (!fs.existsSync(filePath)) {
332
397
  continue;
333
398
  }
334
- // Only read the first 4KB — cwd appears on line 1
335
399
  const fd = fs.openSync(filePath, 'r');
336
- let firstChunk: string;
400
+ let chunk: string;
337
401
  try {
338
- const buf = Buffer.alloc(4096);
339
- const bytesRead = fs.readSync(fd, buf, 0, 4096, 0);
340
- firstChunk = buf.toString('utf-8', 0, bytesRead);
402
+ const buf = Buffer.alloc(READ_BYTES);
403
+ const bytesRead = fs.readSync(fd, buf, 0, READ_BYTES, 0);
404
+ chunk = buf.toString('utf-8', 0, bytesRead);
341
405
  } finally {
342
406
  fs.closeSync(fd);
343
407
  }
344
- const firstLine = firstChunk.split('\n')[0];
345
- if (!firstLine.trim()) {
346
- continue;
347
- }
348
- try {
349
- const entry = JSON.parse(firstLine) as Record<string, unknown>;
350
- if (typeof entry.cwd === 'string' && entry.cwd) {
351
- return entry.cwd;
408
+ const lines = chunk.split('\n');
409
+ // Drop the last line if the chunk was truncated mid-line
410
+ const completeLines = bytesReadEnded(chunk) ? lines : lines.slice(0, -1);
411
+ for (const line of completeLines) {
412
+ if (!line.trim()) {
413
+ continue;
414
+ }
415
+ try {
416
+ const entry = JSON.parse(line) as Record<string, unknown>;
417
+ if (typeof entry.cwd === 'string' && entry.cwd) {
418
+ return entry.cwd;
419
+ }
420
+ } catch {
421
+ // skip malformed line and try the next one
352
422
  }
353
- } catch {
354
- // skip malformed first line
355
423
  }
356
424
  } catch {
357
425
  // skip unreadable files
@@ -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.