@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.
- package/.claude/hooks/notifier.cjs +15 -1
- package/README.md +132 -36
- package/bin/shooter.cjs +98 -29
- package/build/client/_app/immutable/assets/2.Dk9NfqnS.css +1 -0
- package/build/client/_app/immutable/assets/2.Dk9NfqnS.css.br +0 -0
- package/build/client/_app/immutable/assets/2.Dk9NfqnS.css.gz +0 -0
- package/build/client/_app/immutable/assets/3.DHxQoulp.css +1 -0
- package/build/client/_app/immutable/assets/3.DHxQoulp.css.br +0 -0
- package/build/client/_app/immutable/assets/3.DHxQoulp.css.gz +0 -0
- package/build/client/_app/immutable/assets/{3.DGDHCVnW.css → 4.D5l1JxgO.css} +1 -1
- package/build/client/_app/immutable/assets/4.D5l1JxgO.css.br +0 -0
- package/build/client/_app/immutable/assets/4.D5l1JxgO.css.gz +0 -0
- package/build/client/_app/immutable/assets/5.C5qz-NeI.css +1 -0
- package/build/client/_app/immutable/assets/5.C5qz-NeI.css.br +0 -0
- package/build/client/_app/immutable/assets/5.C5qz-NeI.css.gz +0 -0
- package/build/client/_app/immutable/chunks/1mEchsPO.js +1 -0
- package/build/client/_app/immutable/chunks/1mEchsPO.js.br +0 -0
- package/build/client/_app/immutable/chunks/1mEchsPO.js.gz +0 -0
- package/build/client/_app/immutable/chunks/B7X-vhXI.js +1 -0
- package/build/client/_app/immutable/chunks/B7X-vhXI.js.br +0 -0
- package/build/client/_app/immutable/chunks/B7X-vhXI.js.gz +0 -0
- package/build/client/_app/immutable/chunks/BRkqKgVG.js +1 -0
- package/build/client/_app/immutable/chunks/BRkqKgVG.js.br +0 -0
- package/build/client/_app/immutable/chunks/BRkqKgVG.js.gz +0 -0
- package/build/client/_app/immutable/chunks/BfJ-f-Tu.js +1 -0
- package/build/client/_app/immutable/chunks/BfJ-f-Tu.js.br +2 -0
- package/build/client/_app/immutable/chunks/BfJ-f-Tu.js.gz +0 -0
- package/build/client/_app/immutable/chunks/CGMJxf7r.js +1 -0
- package/build/client/_app/immutable/chunks/CGMJxf7r.js.br +0 -0
- package/build/client/_app/immutable/chunks/CGMJxf7r.js.gz +0 -0
- package/build/client/_app/immutable/chunks/{CZHsSL_X.js → CJFjKwJ7.js} +1 -1
- package/build/client/_app/immutable/chunks/CJFjKwJ7.js.br +0 -0
- package/build/client/_app/immutable/chunks/CJFjKwJ7.js.gz +0 -0
- package/build/client/_app/immutable/chunks/CNH2HlKj.js +20 -0
- package/build/client/_app/immutable/chunks/CNH2HlKj.js.br +0 -0
- package/build/client/_app/immutable/chunks/CNH2HlKj.js.gz +0 -0
- package/build/client/_app/immutable/chunks/CR6bkGJW.js +6 -0
- package/build/client/_app/immutable/chunks/CR6bkGJW.js.br +0 -0
- package/build/client/_app/immutable/chunks/CR6bkGJW.js.gz +0 -0
- package/build/client/_app/immutable/chunks/CVtJ6yRM.js +1 -0
- package/build/client/_app/immutable/chunks/CVtJ6yRM.js.br +0 -0
- package/build/client/_app/immutable/chunks/CVtJ6yRM.js.gz +0 -0
- package/build/client/_app/immutable/chunks/{CSoRdFvv.js → CaiJSUi3.js} +1 -1
- package/build/client/_app/immutable/chunks/CaiJSUi3.js.br +0 -0
- package/build/client/_app/immutable/chunks/CaiJSUi3.js.gz +0 -0
- package/build/client/_app/immutable/chunks/{DjsDGxCa.js → CmczWE_d.js} +4 -4
- package/build/client/_app/immutable/chunks/CmczWE_d.js.br +0 -0
- package/build/client/_app/immutable/chunks/CmczWE_d.js.gz +0 -0
- package/build/client/_app/immutable/chunks/{CDVSripB.js → CqfYvnci.js} +1 -1
- package/build/client/_app/immutable/chunks/CqfYvnci.js.br +0 -0
- package/build/client/_app/immutable/chunks/CqfYvnci.js.gz +0 -0
- package/build/client/_app/immutable/chunks/CsgHjHGZ.js +1 -0
- package/build/client/_app/immutable/chunks/CsgHjHGZ.js.br +0 -0
- package/build/client/_app/immutable/chunks/CsgHjHGZ.js.gz +0 -0
- package/build/client/_app/immutable/chunks/{UJOiqIYE.js → CtrCjGZT.js} +1 -1
- package/build/client/_app/immutable/chunks/CtrCjGZT.js.br +0 -0
- package/build/client/_app/immutable/chunks/CtrCjGZT.js.gz +0 -0
- package/build/client/_app/immutable/chunks/DDiOVAd8.js +61 -0
- package/build/client/_app/immutable/chunks/DDiOVAd8.js.br +0 -0
- package/build/client/_app/immutable/chunks/DDiOVAd8.js.gz +0 -0
- package/build/client/_app/immutable/chunks/DVl0sebP.js +2 -0
- package/build/client/_app/immutable/chunks/DVl0sebP.js.br +0 -0
- package/build/client/_app/immutable/chunks/DVl0sebP.js.gz +0 -0
- package/build/client/_app/immutable/chunks/EhLZwqfu.js +3 -0
- package/build/client/_app/immutable/chunks/EhLZwqfu.js.br +0 -0
- package/build/client/_app/immutable/chunks/EhLZwqfu.js.gz +0 -0
- package/build/client/_app/immutable/chunks/gQJcRhou.js +1 -0
- package/build/client/_app/immutable/chunks/gQJcRhou.js.br +0 -0
- package/build/client/_app/immutable/chunks/gQJcRhou.js.gz +0 -0
- package/build/client/_app/immutable/chunks/pRcLbE0d.js +1 -0
- package/build/client/_app/immutable/chunks/pRcLbE0d.js.br +0 -0
- package/build/client/_app/immutable/chunks/pRcLbE0d.js.gz +0 -0
- package/build/client/_app/immutable/chunks/{CF4lQ45j.js → y_g-KC7l.js} +1 -1
- package/build/client/_app/immutable/chunks/y_g-KC7l.js.br +0 -0
- package/build/client/_app/immutable/chunks/y_g-KC7l.js.gz +0 -0
- package/build/client/_app/immutable/entry/app.zJvbFXsj.js +2 -0
- package/build/client/_app/immutable/entry/app.zJvbFXsj.js.br +0 -0
- package/build/client/_app/immutable/entry/app.zJvbFXsj.js.gz +0 -0
- package/build/client/_app/immutable/entry/start.B2Jf5iFd.js +1 -0
- package/build/client/_app/immutable/entry/start.B2Jf5iFd.js.br +2 -0
- package/build/client/_app/immutable/entry/start.B2Jf5iFd.js.gz +0 -0
- package/build/client/_app/immutable/nodes/0.B_E4j3MX.js +1 -0
- package/build/client/_app/immutable/nodes/0.B_E4j3MX.js.br +0 -0
- package/build/client/_app/immutable/nodes/0.B_E4j3MX.js.gz +0 -0
- package/build/client/_app/immutable/nodes/1.B0oFqb8X.js +1 -0
- package/build/client/_app/immutable/nodes/1.B0oFqb8X.js.br +0 -0
- package/build/client/_app/immutable/nodes/1.B0oFqb8X.js.gz +0 -0
- package/build/client/_app/immutable/nodes/2.Bqul0XyM.js +13 -0
- package/build/client/_app/immutable/nodes/2.Bqul0XyM.js.br +0 -0
- package/build/client/_app/immutable/nodes/2.Bqul0XyM.js.gz +0 -0
- package/build/client/_app/immutable/nodes/3.CTqUQKSN.js +9 -0
- package/build/client/_app/immutable/nodes/3.CTqUQKSN.js.br +0 -0
- package/build/client/_app/immutable/nodes/3.CTqUQKSN.js.gz +0 -0
- package/build/client/_app/immutable/nodes/4.B_pbOZoD.js +4 -0
- package/build/client/_app/immutable/nodes/4.B_pbOZoD.js.br +0 -0
- package/build/client/_app/immutable/nodes/4.B_pbOZoD.js.gz +0 -0
- package/build/client/_app/immutable/nodes/5.CdLPNo5-.js +1 -0
- package/build/client/_app/immutable/nodes/5.CdLPNo5-.js.br +0 -0
- package/build/client/_app/immutable/nodes/5.CdLPNo5-.js.gz +0 -0
- package/build/client/_app/immutable/nodes/6.BvjUfHnH.js +1 -0
- package/build/client/_app/immutable/nodes/6.BvjUfHnH.js.br +0 -0
- package/build/client/_app/immutable/nodes/6.BvjUfHnH.js.gz +0 -0
- package/build/client/_app/immutable/nodes/{5.g3R-QfIW.js → 7.5K7Od8ba.js} +3 -3
- package/build/client/_app/immutable/nodes/7.5K7Od8ba.js.br +0 -0
- package/build/client/_app/immutable/nodes/7.5K7Od8ba.js.gz +0 -0
- package/build/client/_app/immutable/nodes/8.Bs1DrW0_.js +2 -0
- package/build/client/_app/immutable/nodes/8.Bs1DrW0_.js.br +0 -0
- package/build/client/_app/immutable/nodes/8.Bs1DrW0_.js.gz +0 -0
- package/build/client/_app/immutable/nodes/9.1fMlGdqv.js +2 -0
- package/build/client/_app/immutable/nodes/9.1fMlGdqv.js.br +0 -0
- package/build/client/_app/immutable/nodes/9.1fMlGdqv.js.gz +0 -0
- package/build/client/_app/version.json +1 -1
- package/build/client/_app/version.json.br +0 -0
- package/build/client/_app/version.json.gz +0 -0
- package/build/server/chunks/0-e1fgD9Mi.js +23 -0
- package/build/server/chunks/0-e1fgD9Mi.js.map +1 -0
- package/build/server/chunks/1-D2_XVthm.js +9 -0
- package/build/server/chunks/{1-BV7u1xGo.js.map → 1-D2_XVthm.js.map} +1 -1
- package/build/server/chunks/2-DADX86JZ.js +21 -0
- package/build/server/chunks/2-DADX86JZ.js.map +1 -0
- package/build/server/chunks/3-CHacdiCg.js +21 -0
- package/build/server/chunks/3-CHacdiCg.js.map +1 -0
- package/build/server/chunks/4-0UE_6Ep-.js +23 -0
- package/build/server/chunks/4-0UE_6Ep-.js.map +1 -0
- package/build/server/chunks/5-BBIP1PzX.js +24 -0
- package/build/server/chunks/5-BBIP1PzX.js.map +1 -0
- package/build/server/chunks/6-CWLNQu6F.js +9 -0
- package/build/server/chunks/6-CWLNQu6F.js.map +1 -0
- package/build/server/chunks/7-DmQ3B8uy.js +9 -0
- package/build/server/chunks/7-DmQ3B8uy.js.map +1 -0
- package/build/server/chunks/8-CnFVjQtZ.js +9 -0
- package/build/server/chunks/8-CnFVjQtZ.js.map +1 -0
- package/build/server/chunks/9-Dw7-P6aF.js +9 -0
- package/build/server/chunks/9-Dw7-P6aF.js.map +1 -0
- package/build/server/chunks/{Button-Cs1aE6ka.js → Button-WKgiLWZI.js} +4 -9
- package/build/server/chunks/Button-WKgiLWZI.js.map +1 -0
- package/build/server/chunks/{EmptyState-DDFH1K8g.js → EmptyState-BUBqASsp.js} +3 -3
- package/build/server/chunks/{EmptyState-DDFH1K8g.js.map → EmptyState-BUBqASsp.js.map} +1 -1
- package/build/server/chunks/{Icon-CEUrotA6.js → Icon-BNBAg85a.js} +3 -3
- package/build/server/chunks/Icon-BNBAg85a.js.map +1 -0
- package/build/server/chunks/{Shimmer-DB8W1zt6.js → Shimmer-C4uBVwxz.js} +2 -2
- package/build/server/chunks/{Shimmer-DB8W1zt6.js.map → Shimmer-C4uBVwxz.js.map} +1 -1
- package/build/server/chunks/{_error.svelte-uCOJNxvr.js → _error.svelte-DkIwmECt.js} +5 -5
- package/build/server/chunks/{_error.svelte-uCOJNxvr.js.map → _error.svelte-DkIwmECt.js.map} +1 -1
- package/build/server/chunks/{_layout.svelte-CtWmEJwe.js → _layout.svelte-DllETxmJ.js} +13 -7
- package/build/server/chunks/_layout.svelte-DllETxmJ.js.map +1 -0
- package/build/server/chunks/_page.svelte-BZSdLKE_.js +118 -0
- package/build/server/chunks/_page.svelte-BZSdLKE_.js.map +1 -0
- package/build/server/chunks/{_page.svelte-CxWcQ0Am.js → _page.svelte-Cmuco1mC.js} +84 -199
- package/build/server/chunks/_page.svelte-Cmuco1mC.js.map +1 -0
- package/build/server/chunks/{_page.svelte-BgevQjq1.js → _page.svelte-Co5sF7W-.js} +12 -11
- package/build/server/chunks/{_page.svelte-BgevQjq1.js.map → _page.svelte-Co5sF7W-.js.map} +1 -1
- package/build/server/chunks/{_page.svelte-DO4oa_LY.js → _page.svelte-CpL3R-VI.js} +8 -8
- package/build/server/chunks/{_page.svelte-DO4oa_LY.js.map → _page.svelte-CpL3R-VI.js.map} +1 -1
- package/build/server/chunks/_page.svelte-DDSzYLUs.js +137 -0
- package/build/server/chunks/_page.svelte-DDSzYLUs.js.map +1 -0
- package/build/server/chunks/_page.svelte-JIkgFUFf.js +26 -0
- package/build/server/chunks/_page.svelte-JIkgFUFf.js.map +1 -0
- package/build/server/chunks/{_page.svelte-CVq6tRb3.js → _page.svelte-Y9-O5a5w.js} +10 -9
- package/build/server/chunks/_page.svelte-Y9-O5a5w.js.map +1 -0
- package/build/server/chunks/{_page.svelte-BcZaKdX9.js → _page.svelte-fcX09N4d.js} +9 -9
- package/build/server/chunks/{_page.svelte-BcZaKdX9.js.map → _page.svelte-fcX09N4d.js.map} +1 -1
- package/build/server/chunks/{_server.ts-DYpJImqd.js → _server.ts-0Xr2fWaq.js} +9 -5
- package/build/server/chunks/_server.ts-0Xr2fWaq.js.map +1 -0
- package/build/server/chunks/{_server.ts-CTpcLUH8.js → _server.ts-2ixC-X3K.js} +20 -5
- package/build/server/chunks/_server.ts-2ixC-X3K.js.map +1 -0
- package/build/server/chunks/{_server.ts-CAxsWKvS.js → _server.ts-40c_epk8.js} +20 -4
- package/build/server/chunks/_server.ts-40c_epk8.js.map +1 -0
- package/build/server/chunks/{_server.ts-WhTJBEJy.js → _server.ts-A9_tRR-K.js} +5 -4
- package/build/server/chunks/{_server.ts-WhTJBEJy.js.map → _server.ts-A9_tRR-K.js.map} +1 -1
- package/build/server/chunks/_server.ts-BRAzC6W1.js +98 -0
- package/build/server/chunks/_server.ts-BRAzC6W1.js.map +1 -0
- package/build/server/chunks/{_server.ts-DB_Kg97c.js → _server.ts-BScvgttw.js} +24 -4
- package/build/server/chunks/_server.ts-BScvgttw.js.map +1 -0
- package/build/server/chunks/{_server.ts-Ch-6iOHp.js → _server.ts-B__YN2kX.js} +121 -87
- package/build/server/chunks/_server.ts-B__YN2kX.js.map +1 -0
- package/build/server/chunks/{_server.ts-tSpgyl1D.js → _server.ts-Bjbr7glm.js} +4 -3
- package/build/server/chunks/_server.ts-Bjbr7glm.js.map +1 -0
- package/build/server/chunks/{_server.ts-COu0vNpd.js → _server.ts-BrqaMMAa.js} +7 -6
- package/build/server/chunks/_server.ts-BrqaMMAa.js.map +1 -0
- package/build/server/chunks/{_server.ts-vekTmWAx.js → _server.ts-BuYyCrnF.js} +6 -4
- package/build/server/chunks/_server.ts-BuYyCrnF.js.map +1 -0
- package/build/server/chunks/{_server.ts-Deok2y88.js → _server.ts-ByIrRtCx.js} +132 -76
- package/build/server/chunks/_server.ts-ByIrRtCx.js.map +1 -0
- package/build/server/chunks/{_server.ts-DYvb9ijZ.js → _server.ts-ByPExYfO.js} +4 -3
- package/build/server/chunks/{_server.ts-DYvb9ijZ.js.map → _server.ts-ByPExYfO.js.map} +1 -1
- package/build/server/chunks/_server.ts-CjpQ10xh.js +123 -0
- package/build/server/chunks/_server.ts-CjpQ10xh.js.map +1 -0
- package/build/server/chunks/_server.ts-CyjDrcZN.js +21 -0
- package/build/server/chunks/_server.ts-CyjDrcZN.js.map +1 -0
- package/build/server/chunks/{_server.ts-DV8zTCF9.js → _server.ts-DOGUMzPx.js} +4 -3
- package/build/server/chunks/{_server.ts-DV8zTCF9.js.map → _server.ts-DOGUMzPx.js.map} +1 -1
- package/build/server/chunks/_server.ts-DZvfyuNj.js +15 -0
- package/build/server/chunks/_server.ts-DZvfyuNj.js.map +1 -0
- package/build/server/chunks/{_server.ts-XzT2UHM1.js → _server.ts-DkPPTUPo.js} +4 -3
- package/build/server/chunks/{_server.ts-XzT2UHM1.js.map → _server.ts-DkPPTUPo.js.map} +1 -1
- package/build/server/chunks/{auth-DeCdZ83n.js → auth-DuunT7Cg.js} +2 -2
- package/build/server/chunks/{auth-DeCdZ83n.js.map → auth-DuunT7Cg.js.map} +1 -1
- package/build/server/chunks/{client-BdGHe_hY.js → client-DRtPDkMh.js} +4 -4
- package/build/server/chunks/{client-BdGHe_hY.js.map → client-DRtPDkMh.js.map} +1 -1
- package/build/server/chunks/client2-bqqmu0b7.js +7 -0
- package/build/server/chunks/{client2-CCBGA-2V.js.map → client2-bqqmu0b7.js.map} +1 -1
- package/build/server/chunks/close-BGlLztTb.js +192 -0
- package/build/server/chunks/close-BGlLztTb.js.map +1 -0
- package/build/server/chunks/events-handler-Dm1mNPQP.js +20 -0
- package/build/server/chunks/events-handler-Dm1mNPQP.js.map +1 -0
- package/build/server/chunks/html-FW6Ia4bL.js +8 -0
- package/build/server/chunks/html-FW6Ia4bL.js.map +1 -0
- package/build/server/chunks/{shared-server-sSGG17Df.js → index-CoD1IJuy.js} +2 -11
- package/build/server/chunks/index-CoD1IJuy.js.map +1 -0
- package/build/server/chunks/{index-DwaY1cAm.js → index-DP9bWJrR.js} +2 -2
- package/build/server/chunks/{index-DwaY1cAm.js.map → index-DP9bWJrR.js.map} +1 -1
- package/build/server/chunks/{index-server-CrDaL06Y.js → index-server-BUmV4MIG.js} +2 -2
- package/build/server/chunks/index-server-BUmV4MIG.js.map +1 -0
- package/build/server/chunks/index-server2-BJrT0wnA.js +5 -0
- package/build/server/chunks/index-server2-BJrT0wnA.js.map +1 -0
- package/build/server/chunks/{index2-CgclKpUj.js → index2-D5Y19GKR.js} +2 -2
- package/build/server/chunks/index2-D5Y19GKR.js.map +1 -0
- package/build/server/chunks/{library-apns-BqJbvSKh.js → library-apns-Cf-E-DhM.js} +5 -2
- package/build/server/chunks/library-apns-Cf-E-DhM.js.map +1 -0
- package/build/server/chunks/providers-DtstoHQ0.js +17 -0
- package/build/server/chunks/providers-DtstoHQ0.js.map +1 -0
- package/build/server/chunks/{pty-manager-BQVB7IVj.js → pty-manager-TyMUpDA9.js} +41 -9
- package/build/server/chunks/pty-manager-TyMUpDA9.js.map +1 -0
- package/build/server/chunks/{root-DDSnEAZv.js → root-CATOR_0t.js} +2 -2
- package/build/server/chunks/root-CATOR_0t.js.map +1 -0
- package/build/server/chunks/shared-server-DaWdgxVh.js +11 -0
- package/build/server/chunks/shared-server-DaWdgxVh.js.map +1 -0
- package/build/server/chunks/{state.svelte-hBbXlUak.js → state.svelte-CftllyvC.js} +3 -3
- package/build/server/chunks/state.svelte-CftllyvC.js.map +1 -0
- package/build/server/chunks/{stores-DHNzYNpX.js → stores-BjL57aOK.js} +4 -4
- package/build/server/chunks/{stores-DHNzYNpX.js.map → stores-BjL57aOK.js.map} +1 -1
- package/build/server/index.js +173 -6
- package/build/server/index.js.map +1 -1
- package/build/server/manifest.js +53 -30
- package/build/server/manifest.js.map +1 -1
- package/package.json +28 -7
- package/scripts/dev.mjs +361 -0
- package/scripts/install.sh +133 -73
- package/scripts/{fix-generated-types.sh → postgen-types.sh} +2 -2
- package/scripts/setup.cjs +440 -244
- package/scripts/vercel-env-commands.sh +3 -3
- package/server.ts +3 -3
- package/src/app.html +163 -0
- package/src/lib/modules/client/activity/ActivityFeed.svelte +279 -0
- package/src/lib/modules/client/activity/index.ts +8 -0
- package/src/lib/modules/client/activity/store.svelte.ts +478 -0
- package/src/lib/modules/client/activity/summarizer.ts +224 -0
- package/src/lib/modules/client/common/Card.svelte +2 -9
- package/src/lib/modules/client/common/EmptyState.svelte +2 -20
- package/src/lib/modules/client/common/Icon.svelte +3 -7
- package/src/lib/modules/client/common/StatusBadge.svelte +2 -4
- package/src/lib/modules/client/common/config-guard.ts +22 -2
- package/src/lib/modules/client/common/index.ts +1 -1
- package/src/lib/modules/client/common/time.ts +27 -9
- package/src/lib/modules/client/dashboard/DashboardCard.svelte +374 -0
- package/src/lib/modules/client/dashboard/DashboardView.svelte +66 -0
- package/src/lib/modules/client/dashboard/index.ts +12 -0
- package/src/lib/modules/client/dashboard/store.svelte.ts +663 -0
- package/src/lib/modules/client/dashboard/summarizer.ts +205 -0
- package/src/lib/modules/client/neurolink/fetch-proxy.ts +70 -0
- package/src/lib/modules/client/neurolink/provider-config.ts +111 -0
- package/src/lib/modules/client/terminal/ChatView.svelte +46 -43
- package/src/lib/modules/client/terminal/CommandPalette.svelte +3 -12
- package/src/lib/modules/client/terminal/ConnectionStatus.svelte +3 -6
- package/src/lib/modules/client/terminal/LaunchSheet.svelte +10 -21
- package/src/lib/modules/client/terminal/QuickKeys.svelte +4 -11
- package/src/lib/modules/client/terminal/ShortcutsHelp.svelte +3 -6
- package/src/lib/modules/client/terminal/keyboard-shortcuts.ts +5 -7
- package/src/lib/modules/client/terminal/xterm-wrapper.ts +27 -47
- package/src/lib/modules/server/apn/library-apns.ts +6 -3
- package/src/lib/modules/server/apn/notification-history.ts +2 -2
- package/src/lib/modules/server/apn/notification-sessions.ts +1 -3
- package/src/lib/modules/server/apn/pending-requests.ts +1 -1
- package/src/lib/modules/server/apn/types.ts +2 -52
- package/src/lib/modules/server/cli/index.ts +1 -30
- package/src/lib/modules/server/cli/runner.ts +7 -15
- package/src/lib/modules/server/fcm/fcm-service.ts +2 -2
- package/src/lib/modules/server/sessions/jsonl-parser.ts +97 -42
- package/src/lib/modules/server/sessions/jsonl-reader.ts +69 -60
- package/src/lib/modules/server/sessions/opencode-reader.ts +1 -1
- package/src/lib/modules/server/sessions/process-detector.ts +72 -31
- package/src/lib/modules/server/sessions/types.ts +2 -42
- package/src/lib/modules/server/terminal/holder-client.ts +11 -35
- package/src/lib/modules/server/terminal/opencode-watcher.ts +16 -24
- package/src/lib/modules/server/terminal/pty-manager.ts +40 -45
- package/src/lib/modules/server/terminal/session-watcher.ts +15 -17
- package/src/lib/modules/server/terminal/terminal-store.ts +1 -1
- package/src/lib/modules/server/ws/events-handler.ts +1 -16
- package/src/lib/modules/server/ws/keepalive.ts +1 -5
- package/src/lib/modules/server/ws/server.ts +1 -1
- package/src/lib/modules/server/ws/session-handler.ts +20 -86
- package/src/lib/modules/server/ws/terminal-handler.ts +28 -51
- package/src/lib/modules/server/ws/ticket-store.ts +1 -1
- package/src/lib/modules/shared/providers.ts +21 -0
- package/src/lib/types/activity.ts +18 -0
- package/src/lib/types/apn.ts +43 -0
- package/src/lib/types/cli.ts +39 -0
- package/src/lib/types/common.ts +39 -0
- package/src/lib/types/dashboard.ts +4 -0
- package/src/lib/types/generated/Client.ts +1656 -0
- package/src/{generated/types → lib/types/generated}/WsProtocol.ts +344 -2
- package/src/lib/types/index.ts +28 -0
- package/src/lib/types/neurolink.ts +4 -0
- package/src/lib/types/server.ts +93 -0
- package/src/lib/types/sessions.ts +59 -0
- package/src/lib/types/terminal-client.ts +132 -0
- package/src/lib/types/ws.ts +161 -0
- package/src/routes/+error.svelte +7 -2
- package/src/routes/+layout.server.ts +9 -0
- package/src/routes/+layout.svelte +36 -7
- package/src/routes/+page.server.ts +7 -0
- package/src/routes/+page.svelte +85 -35
- package/src/routes/activity/+page.server.ts +7 -0
- package/src/routes/activity/+page.svelte +58 -0
- package/src/routes/api/health/+server.ts +32 -19
- package/src/routes/api/neurolink-proxy/+server.ts +136 -0
- package/src/routes/api/notify/+server.ts +159 -84
- package/src/routes/api/sessions/+server.ts +1 -1
- package/src/routes/api/sessions/connect/+server.ts +10 -6
- package/src/routes/api/terminals/+server.ts +20 -1
- package/src/routes/api/terminals/[id]/+server.ts +16 -2
- package/src/routes/api/webhook/+server.ts +5 -33
- package/src/routes/api/ws-ticket/+server.ts +4 -4
- package/src/routes/config/+page.server.ts +9 -0
- package/src/routes/config/+page.svelte +118 -25
- package/src/routes/neurolink/+page.server.ts +10 -0
- package/src/routes/neurolink/+page.svelte +331 -0
- package/src/routes/project/+page.svelte +17 -12
- package/src/routes/session/[id]/+page.svelte +146 -62
- package/src/routes/terminals/+page.svelte +2 -2
- package/src/routes/terminals/[id]/+page.svelte +99 -88
- package/svelte.config.js +1 -3
- package/tsconfig.json +1 -0
- package/build/client/_app/immutable/assets/2.CAShZ7lQ.css +0 -1
- package/build/client/_app/immutable/assets/2.CAShZ7lQ.css.br +0 -1
- package/build/client/_app/immutable/assets/2.CAShZ7lQ.css.gz +0 -0
- package/build/client/_app/immutable/assets/3.DGDHCVnW.css.br +0 -0
- package/build/client/_app/immutable/assets/3.DGDHCVnW.css.gz +0 -0
- package/build/client/_app/immutable/chunks/B5NAKyil.js +0 -20
- package/build/client/_app/immutable/chunks/B5NAKyil.js.br +0 -0
- package/build/client/_app/immutable/chunks/B5NAKyil.js.gz +0 -0
- package/build/client/_app/immutable/chunks/B8XegpSE.js +0 -1
- package/build/client/_app/immutable/chunks/B8XegpSE.js.br +0 -0
- package/build/client/_app/immutable/chunks/B8XegpSE.js.gz +0 -0
- package/build/client/_app/immutable/chunks/B8zoBsv3.js +0 -6
- package/build/client/_app/immutable/chunks/B8zoBsv3.js.br +0 -0
- package/build/client/_app/immutable/chunks/B8zoBsv3.js.gz +0 -0
- package/build/client/_app/immutable/chunks/BN1NjBrw.js +0 -1
- package/build/client/_app/immutable/chunks/BN1NjBrw.js.br +0 -0
- package/build/client/_app/immutable/chunks/BN1NjBrw.js.gz +0 -0
- package/build/client/_app/immutable/chunks/BOYo8yTr.js +0 -1
- package/build/client/_app/immutable/chunks/BOYo8yTr.js.br +0 -0
- package/build/client/_app/immutable/chunks/BOYo8yTr.js.gz +0 -0
- package/build/client/_app/immutable/chunks/Bu1aqm5j.js +0 -1
- package/build/client/_app/immutable/chunks/Bu1aqm5j.js.br +0 -0
- package/build/client/_app/immutable/chunks/Bu1aqm5j.js.gz +0 -0
- package/build/client/_app/immutable/chunks/CDVSripB.js.br +0 -0
- package/build/client/_app/immutable/chunks/CDVSripB.js.gz +0 -0
- package/build/client/_app/immutable/chunks/CF4lQ45j.js.br +0 -0
- package/build/client/_app/immutable/chunks/CF4lQ45j.js.gz +0 -0
- package/build/client/_app/immutable/chunks/CQjSATpv.js +0 -61
- package/build/client/_app/immutable/chunks/CQjSATpv.js.br +0 -0
- package/build/client/_app/immutable/chunks/CQjSATpv.js.gz +0 -0
- package/build/client/_app/immutable/chunks/CSoRdFvv.js.br +0 -0
- package/build/client/_app/immutable/chunks/CSoRdFvv.js.gz +0 -0
- package/build/client/_app/immutable/chunks/CZHsSL_X.js.br +0 -0
- package/build/client/_app/immutable/chunks/CZHsSL_X.js.gz +0 -0
- package/build/client/_app/immutable/chunks/DSU1n5N_.js +0 -1
- package/build/client/_app/immutable/chunks/DSU1n5N_.js.br +0 -0
- package/build/client/_app/immutable/chunks/DSU1n5N_.js.gz +0 -0
- package/build/client/_app/immutable/chunks/DVkn4r72.js +0 -1
- package/build/client/_app/immutable/chunks/DVkn4r72.js.br +0 -0
- package/build/client/_app/immutable/chunks/DVkn4r72.js.gz +0 -0
- package/build/client/_app/immutable/chunks/DjsDGxCa.js.br +0 -0
- package/build/client/_app/immutable/chunks/DjsDGxCa.js.gz +0 -0
- package/build/client/_app/immutable/chunks/UJOiqIYE.js.br +0 -0
- package/build/client/_app/immutable/chunks/UJOiqIYE.js.gz +0 -0
- package/build/client/_app/immutable/chunks/r0JawsZc.js +0 -2
- package/build/client/_app/immutable/chunks/r0JawsZc.js.br +0 -0
- package/build/client/_app/immutable/chunks/r0JawsZc.js.gz +0 -0
- package/build/client/_app/immutable/entry/app.DwWiuoEC.js +0 -2
- package/build/client/_app/immutable/entry/app.DwWiuoEC.js.br +0 -0
- package/build/client/_app/immutable/entry/app.DwWiuoEC.js.gz +0 -0
- package/build/client/_app/immutable/entry/start.DG8BMhrh.js +0 -1
- package/build/client/_app/immutable/entry/start.DG8BMhrh.js.br +0 -0
- package/build/client/_app/immutable/entry/start.DG8BMhrh.js.gz +0 -0
- package/build/client/_app/immutable/nodes/0.ejabgzDQ.js +0 -1
- package/build/client/_app/immutable/nodes/0.ejabgzDQ.js.br +0 -0
- package/build/client/_app/immutable/nodes/0.ejabgzDQ.js.gz +0 -0
- package/build/client/_app/immutable/nodes/1.BFK7Ubrr.js +0 -1
- package/build/client/_app/immutable/nodes/1.BFK7Ubrr.js.br +0 -0
- package/build/client/_app/immutable/nodes/1.BFK7Ubrr.js.gz +0 -0
- package/build/client/_app/immutable/nodes/2.DV3saFiY.js +0 -1
- package/build/client/_app/immutable/nodes/2.DV3saFiY.js.br +0 -0
- package/build/client/_app/immutable/nodes/2.DV3saFiY.js.gz +0 -0
- package/build/client/_app/immutable/nodes/3.3yohCM25.js +0 -3
- package/build/client/_app/immutable/nodes/3.3yohCM25.js.br +0 -0
- package/build/client/_app/immutable/nodes/3.3yohCM25.js.gz +0 -0
- package/build/client/_app/immutable/nodes/4.D6NIf10D.js +0 -1
- package/build/client/_app/immutable/nodes/4.D6NIf10D.js.br +0 -0
- package/build/client/_app/immutable/nodes/4.D6NIf10D.js.gz +0 -0
- package/build/client/_app/immutable/nodes/5.g3R-QfIW.js.br +0 -0
- package/build/client/_app/immutable/nodes/5.g3R-QfIW.js.gz +0 -0
- package/build/client/_app/immutable/nodes/6.DSpd_nYK.js +0 -2
- package/build/client/_app/immutable/nodes/6.DSpd_nYK.js.br +0 -0
- package/build/client/_app/immutable/nodes/6.DSpd_nYK.js.gz +0 -0
- package/build/client/_app/immutable/nodes/7.F9WBFTz2.js +0 -2
- package/build/client/_app/immutable/nodes/7.F9WBFTz2.js.br +0 -0
- package/build/client/_app/immutable/nodes/7.F9WBFTz2.js.gz +0 -0
- package/build/server/chunks/0-ePgrkfG9.js +0 -9
- package/build/server/chunks/0-ePgrkfG9.js.map +0 -1
- package/build/server/chunks/1-BV7u1xGo.js +0 -9
- package/build/server/chunks/2-3p1kyvjQ.js +0 -9
- package/build/server/chunks/2-3p1kyvjQ.js.map +0 -1
- package/build/server/chunks/3-Ck7ewhOX.js +0 -9
- package/build/server/chunks/3-Ck7ewhOX.js.map +0 -1
- package/build/server/chunks/4-ChFYfo_S.js +0 -9
- package/build/server/chunks/4-ChFYfo_S.js.map +0 -1
- package/build/server/chunks/5-q-tQLBBu.js +0 -9
- package/build/server/chunks/5-q-tQLBBu.js.map +0 -1
- package/build/server/chunks/6-BIaAbm8b.js +0 -9
- package/build/server/chunks/6-BIaAbm8b.js.map +0 -1
- package/build/server/chunks/7--TmbCgrH.js +0 -9
- package/build/server/chunks/7--TmbCgrH.js.map +0 -1
- package/build/server/chunks/Button-Cs1aE6ka.js.map +0 -1
- package/build/server/chunks/Icon-CEUrotA6.js.map +0 -1
- package/build/server/chunks/_layout.svelte-CtWmEJwe.js.map +0 -1
- package/build/server/chunks/_page.svelte-BdYynOck.js +0 -85
- package/build/server/chunks/_page.svelte-BdYynOck.js.map +0 -1
- package/build/server/chunks/_page.svelte-CVq6tRb3.js.map +0 -1
- package/build/server/chunks/_page.svelte-CxWcQ0Am.js.map +0 -1
- package/build/server/chunks/_server.ts-BStnNIcq.js +0 -34
- package/build/server/chunks/_server.ts-BStnNIcq.js.map +0 -1
- package/build/server/chunks/_server.ts-CAxsWKvS.js.map +0 -1
- package/build/server/chunks/_server.ts-COu0vNpd.js.map +0 -1
- package/build/server/chunks/_server.ts-CTpcLUH8.js.map +0 -1
- package/build/server/chunks/_server.ts-Cf84YIaW.js +0 -25
- package/build/server/chunks/_server.ts-Cf84YIaW.js.map +0 -1
- package/build/server/chunks/_server.ts-Ch-6iOHp.js.map +0 -1
- package/build/server/chunks/_server.ts-CtH0dhUp.js +0 -71
- package/build/server/chunks/_server.ts-CtH0dhUp.js.map +0 -1
- package/build/server/chunks/_server.ts-DB_Kg97c.js.map +0 -1
- package/build/server/chunks/_server.ts-DYpJImqd.js.map +0 -1
- package/build/server/chunks/_server.ts-Deok2y88.js.map +0 -1
- package/build/server/chunks/_server.ts-tSpgyl1D.js.map +0 -1
- package/build/server/chunks/_server.ts-vekTmWAx.js.map +0 -1
- package/build/server/chunks/client2-CCBGA-2V.js +0 -7
- package/build/server/chunks/index-server-CrDaL06Y.js.map +0 -1
- package/build/server/chunks/index2-CgclKpUj.js.map +0 -1
- package/build/server/chunks/library-apns-BqJbvSKh.js.map +0 -1
- package/build/server/chunks/pty-manager-BQVB7IVj.js.map +0 -1
- package/build/server/chunks/root-DDSnEAZv.js.map +0 -1
- package/build/server/chunks/shared-server-sSGG17Df.js.map +0 -1
- package/build/server/chunks/state.svelte-hBbXlUak.js.map +0 -1
- package/src/generated/types/Client.ts +0 -589
- package/src/lib/types/config.ts +0 -1
- /package/build/client/_app/immutable/assets/{4.BFUut--w.css → 6.BFUut--w.css} +0 -0
- /package/build/client/_app/immutable/assets/{4.BFUut--w.css.br → 6.BFUut--w.css.br} +0 -0
- /package/build/client/_app/immutable/assets/{4.BFUut--w.css.gz → 6.BFUut--w.css.gz} +0 -0
- /package/build/client/_app/immutable/assets/{5.BTOx7yt7.css → 7.BTOx7yt7.css} +0 -0
- /package/build/client/_app/immutable/assets/{5.BTOx7yt7.css.br → 7.BTOx7yt7.css.br} +0 -0
- /package/build/client/_app/immutable/assets/{5.BTOx7yt7.css.gz → 7.BTOx7yt7.css.gz} +0 -0
- /package/build/client/_app/immutable/assets/{6.eZGZN-BF.css → 8.eZGZN-BF.css} +0 -0
- /package/build/client/_app/immutable/assets/{6.eZGZN-BF.css.br → 8.eZGZN-BF.css.br} +0 -0
- /package/build/client/_app/immutable/assets/{6.eZGZN-BF.css.gz → 8.eZGZN-BF.css.gz} +0 -0
- /package/build/client/_app/immutable/assets/{7.DwS5ZHBh.css → 9.DwS5ZHBh.css} +0 -0
- /package/build/client/_app/immutable/assets/{7.DwS5ZHBh.css.br → 9.DwS5ZHBh.css.br} +0 -0
- /package/build/client/_app/immutable/assets/{7.DwS5ZHBh.css.gz → 9.DwS5ZHBh.css.gz} +0 -0
- /package/src/{generated/types → lib/types/generated}/API.ts +0 -0
- /package/src/{generated/types → lib/types/generated}/APN.ts +0 -0
- /package/src/{generated/types → lib/types/generated}/CLI.ts +0 -0
- /package/src/{generated/types → lib/types/generated}/Config.ts +0 -0
- /package/src/{generated/types → lib/types/generated}/Holder.ts +0 -0
- /package/src/{generated/types → lib/types/generated}/JWT.ts +0 -0
- /package/src/{generated/types → lib/types/generated}/Notification.ts +0 -0
- /package/src/{generated/types → lib/types/generated}/OpenCode.ts +0 -0
- /package/src/{generated/types → lib/types/generated}/Sessions.ts +0 -0
- /package/src/{generated/types → lib/types/generated}/Terminal.ts +0 -0
- /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 '
|
|
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
|
-
|
|
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
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
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
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
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
|
|
161
|
+
isError: typeof block.is_error === 'boolean' ? block.is_error : false,
|
|
110
162
|
output: output.slice(0, 2000),
|
|
111
|
-
toolUseId: block
|
|
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:
|
|
171
|
+
id: entryUuid || `user-${messageIndex}`,
|
|
120
172
|
parts: parts.filter((p) => p.type === 'text'),
|
|
121
173
|
role: 'user',
|
|
122
|
-
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-${
|
|
181
|
+
id: `tool-result-${entryUuid || messageIndex}`,
|
|
130
182
|
parts: toolResults,
|
|
131
183
|
role: 'system',
|
|
132
|
-
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
|
|
142
|
-
const msgId = msg
|
|
193
|
+
const blocks = toContentBlocks(msg.content);
|
|
194
|
+
const msgId = str(msg, 'id') || entryUuid;
|
|
143
195
|
|
|
144
|
-
for (const block of
|
|
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:
|
|
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"')) {
|
|
239
|
-
|
|
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
|
-
|
|
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 '
|
|
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 {
|
|
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
|
-
*
|
|
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
|
-
//
|
|
2
|
-
|
|
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 {
|
|
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
|
|
137
|
-
exited: info
|
|
138
|
-
pid: info
|
|
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
|