@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.
- package/README.md +24 -20
- package/bin/shooter.cjs +68 -17
- 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/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/{CiF38mQq.js → Dc_Gg2H6.js} +1 -1
- package/build/client/_app/immutable/chunks/Dc_Gg2H6.js.br +0 -0
- package/build/client/_app/immutable/chunks/Dc_Gg2H6.js.gz +0 -0
- package/build/client/_app/immutable/chunks/{CRbaG9cv.js → DlnAjkg1.js} +1 -1
- package/build/client/_app/immutable/chunks/DlnAjkg1.js.br +0 -0
- package/build/client/_app/immutable/chunks/{CRbaG9cv.js.gz → DlnAjkg1.js.gz} +0 -0
- package/build/client/_app/immutable/chunks/YKoRJzXZ.js +3 -0
- package/build/client/_app/immutable/chunks/YKoRJzXZ.js.br +0 -0
- package/build/client/_app/immutable/chunks/YKoRJzXZ.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/entry/app.CFPgQOa8.js +2 -0
- package/build/client/_app/immutable/entry/app.CFPgQOa8.js.br +0 -0
- package/build/client/_app/immutable/entry/app.CFPgQOa8.js.gz +0 -0
- package/build/client/_app/immutable/entry/start.BnJOVqhI.js +1 -0
- package/build/client/_app/immutable/entry/start.BnJOVqhI.js.br +2 -0
- package/build/client/_app/immutable/entry/start.BnJOVqhI.js.gz +0 -0
- package/build/client/_app/immutable/nodes/0.DR-BBF5r.js +1 -0
- package/build/client/_app/immutable/nodes/0.DR-BBF5r.js.br +0 -0
- package/build/client/_app/immutable/nodes/0.DR-BBF5r.js.gz +0 -0
- package/build/client/_app/immutable/nodes/1.CNm6rAwf.js +1 -0
- package/build/client/_app/immutable/nodes/1.CNm6rAwf.js.br +0 -0
- package/build/client/_app/immutable/nodes/1.CNm6rAwf.js.gz +0 -0
- package/build/client/_app/immutable/nodes/2.B08usYzr.js +13 -0
- package/build/client/_app/immutable/nodes/2.B08usYzr.js.br +0 -0
- package/build/client/_app/immutable/nodes/2.B08usYzr.js.gz +0 -0
- package/build/client/_app/immutable/nodes/3.CsY6J5HS.js +9 -0
- package/build/client/_app/immutable/nodes/3.CsY6J5HS.js.br +0 -0
- package/build/client/_app/immutable/nodes/3.CsY6J5HS.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.CbQQ3FtZ.js +1 -0
- package/build/client/_app/immutable/nodes/6.CbQQ3FtZ.js.br +0 -0
- package/build/client/_app/immutable/nodes/6.CbQQ3FtZ.js.gz +0 -0
- package/build/client/_app/immutable/nodes/{5.DIkXVP4q.js → 7.CCKgiNNk.js} +3 -3
- package/build/client/_app/immutable/nodes/7.CCKgiNNk.js.br +0 -0
- package/build/client/_app/immutable/nodes/7.CCKgiNNk.js.gz +0 -0
- package/build/client/_app/immutable/nodes/8.C7AaheUD.js +2 -0
- package/build/client/_app/immutable/nodes/8.C7AaheUD.js.br +0 -0
- package/build/client/_app/immutable/nodes/8.C7AaheUD.js.gz +0 -0
- package/build/client/_app/immutable/nodes/9.DfL9kMC4.js +2 -0
- package/build/client/_app/immutable/nodes/9.DfL9kMC4.js.br +0 -0
- package/build/client/_app/immutable/nodes/9.DfL9kMC4.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-DC2VLooL.js +23 -0
- package/build/server/chunks/0-DC2VLooL.js.map +1 -0
- package/build/server/chunks/1-XJaf8Jvf.js +9 -0
- package/build/server/chunks/{1-D0N7vVhH.js.map → 1-XJaf8Jvf.js.map} +1 -1
- package/build/server/chunks/2-D4Cx-1QL.js +21 -0
- package/build/server/chunks/2-D4Cx-1QL.js.map +1 -0
- package/build/server/chunks/3-CVhIEP-u.js +21 -0
- package/build/server/chunks/3-CVhIEP-u.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-QFSbzRMP.js +9 -0
- package/build/server/chunks/6-QFSbzRMP.js.map +1 -0
- package/build/server/chunks/7-CZ_YGjMV.js +9 -0
- package/build/server/chunks/7-CZ_YGjMV.js.map +1 -0
- package/build/server/chunks/8-Xe2Rugb4.js +9 -0
- package/build/server/chunks/8-Xe2Rugb4.js.map +1 -0
- package/build/server/chunks/9-IwHpC4SO.js +9 -0
- package/build/server/chunks/9-IwHpC4SO.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-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-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/{_server.ts-Deok2y88.js → _server.ts-Ds_SUGC3.js} +184 -90
- package/build/server/chunks/_server.ts-Ds_SUGC3.js.map +1 -0
- package/build/server/chunks/{_server.ts-Ch-6iOHp.js → _server.ts-G8OeADGj.js} +141 -89
- package/build/server/chunks/_server.ts-G8OeADGj.js.map +1 -0
- 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 +24 -6
- package/scripts/dev.mjs +361 -0
- package/scripts/install.sh +11 -3
- package/scripts/{fix-generated-types.sh → postgen-types.sh} +2 -2
- package/scripts/setup.cjs +219 -24
- 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 +144 -76
- 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 +190 -87
- 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/BIaXC2t9.js +0 -1
- package/build/client/_app/immutable/chunks/BIaXC2t9.js.br +0 -0
- package/build/client/_app/immutable/chunks/BIaXC2t9.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/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/CRbaG9cv.js.br +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/CiF38mQq.js.br +0 -0
- package/build/client/_app/immutable/chunks/CiF38mQq.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.CU7KVZja.js +0 -2
- package/build/client/_app/immutable/entry/app.CU7KVZja.js.br +0 -0
- package/build/client/_app/immutable/entry/app.CU7KVZja.js.gz +0 -0
- package/build/client/_app/immutable/entry/start.RAMZY19t.js +0 -1
- package/build/client/_app/immutable/entry/start.RAMZY19t.js.br +0 -2
- package/build/client/_app/immutable/entry/start.RAMZY19t.js.gz +0 -0
- package/build/client/_app/immutable/nodes/0.Bi3XYMSu.js +0 -1
- package/build/client/_app/immutable/nodes/0.Bi3XYMSu.js.br +0 -0
- package/build/client/_app/immutable/nodes/0.Bi3XYMSu.js.gz +0 -0
- package/build/client/_app/immutable/nodes/1.DTmfBFmm.js +0 -1
- package/build/client/_app/immutable/nodes/1.DTmfBFmm.js.br +0 -0
- package/build/client/_app/immutable/nodes/1.DTmfBFmm.js.gz +0 -0
- package/build/client/_app/immutable/nodes/2.Cm269yzt.js +0 -1
- package/build/client/_app/immutable/nodes/2.Cm269yzt.js.br +0 -0
- package/build/client/_app/immutable/nodes/2.Cm269yzt.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.C25c5hMg.js +0 -1
- package/build/client/_app/immutable/nodes/4.C25c5hMg.js.br +0 -0
- package/build/client/_app/immutable/nodes/4.C25c5hMg.js.gz +0 -0
- package/build/client/_app/immutable/nodes/5.DIkXVP4q.js.br +0 -0
- package/build/client/_app/immutable/nodes/5.DIkXVP4q.js.gz +0 -0
- package/build/client/_app/immutable/nodes/6.BPL-HzUX.js +0 -2
- package/build/client/_app/immutable/nodes/6.BPL-HzUX.js.br +0 -0
- package/build/client/_app/immutable/nodes/6.BPL-HzUX.js.gz +0 -0
- package/build/client/_app/immutable/nodes/7.IgEqce53.js +0 -2
- package/build/client/_app/immutable/nodes/7.IgEqce53.js.br +0 -0
- package/build/client/_app/immutable/nodes/7.IgEqce53.js.gz +0 -0
- package/build/server/chunks/0-DiORznXb.js +0 -9
- package/build/server/chunks/0-DiORznXb.js.map +0 -1
- package/build/server/chunks/1-D0N7vVhH.js +0 -9
- package/build/server/chunks/2-DfSav7a7.js +0 -9
- package/build/server/chunks/2-DfSav7a7.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-DV5MZUz_.js +0 -9
- package/build/server/chunks/4-DV5MZUz_.js.map +0 -1
- package/build/server/chunks/5-DJhoAjb0.js +0 -9
- package/build/server/chunks/5-DJhoAjb0.js.map +0 -1
- package/build/server/chunks/6-Cp8CzYbr.js +0 -9
- package/build/server/chunks/6-Cp8CzYbr.js.map +0 -1
- package/build/server/chunks/7-BA4xzUj3.js +0 -9
- package/build/server/chunks/7-BA4xzUj3.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);
|
|
@@ -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
|
|
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"')) {
|
|
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;
|
|
349
|
+
if (line.includes('"type":"user"') || line.includes('"type":"assistant"')) {
|
|
350
|
+
messageCount++;
|
|
247
351
|
}
|
|
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;
|
|
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
|
|
400
|
+
let chunk: string;
|
|
337
401
|
try {
|
|
338
|
-
const buf = Buffer.alloc(
|
|
339
|
-
const bytesRead = fs.readSync(fd, buf, 0,
|
|
340
|
-
|
|
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
|
|
345
|
-
if
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
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 '
|
|
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.
|