@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
|
@@ -12,17 +12,18 @@
|
|
|
12
12
|
*/
|
|
13
13
|
|
|
14
14
|
import type {
|
|
15
|
+
ConversationMessage,
|
|
16
|
+
MessagePart,
|
|
15
17
|
OpenCodeMessage,
|
|
16
18
|
OpenCodePart,
|
|
17
19
|
OpenCodePartData,
|
|
18
20
|
OpenCodeSession,
|
|
19
|
-
|
|
21
|
+
OpenCodeWatchState as WatchState,
|
|
22
|
+
} from '$lib/types';
|
|
20
23
|
|
|
21
24
|
import Database from 'better-sqlite3';
|
|
22
25
|
import * as fs from 'fs';
|
|
23
26
|
|
|
24
|
-
import type { ConversationMessage, MessagePart } from '../sessions/types';
|
|
25
|
-
|
|
26
27
|
import { resolveOpenCodeDbPath } from '../sessions/opencode-db-path';
|
|
27
28
|
|
|
28
29
|
// ── Constants ────────────────────────────────────────────────────────
|
|
@@ -35,24 +36,6 @@ const POLL_INTERVAL_MS = 2000;
|
|
|
35
36
|
/** Maximum parameters per SQLite IN clause (SQLite limit is 999). */
|
|
36
37
|
const SQLITE_MAX_PARAMS = 500;
|
|
37
38
|
|
|
38
|
-
// ── Per-session Watcher State ────────────────────────────────────────
|
|
39
|
-
// WatchState is a runtime/behavioral type (callbacks, emittedSets,
|
|
40
|
-
// intervalHandle) and stays local.
|
|
41
|
-
|
|
42
|
-
interface WatchState {
|
|
43
|
-
callbacks: Set<(messages: ConversationMessage[]) => void>;
|
|
44
|
-
/** Set of message IDs we have already emitted, to avoid duplicates. */
|
|
45
|
-
emittedMessageIds: Set<string>;
|
|
46
|
-
/** Map of part ID to last-seen time_updated, to detect in-place updates. */
|
|
47
|
-
emittedPartUpdatedAt: Map<string, number>;
|
|
48
|
-
intervalHandle: ReturnType<typeof setInterval>;
|
|
49
|
-
/** Highest time_created we have seen for messages (milliseconds). */
|
|
50
|
-
lastMessageTime: number;
|
|
51
|
-
/** Highest time_updated we have seen for parts (milliseconds). */
|
|
52
|
-
lastPartTime: number;
|
|
53
|
-
sessionId: string;
|
|
54
|
-
}
|
|
55
|
-
|
|
56
39
|
class OpenCodeWatcher {
|
|
57
40
|
private watchers = new Map<string, WatchState>();
|
|
58
41
|
|
|
@@ -156,7 +139,10 @@ class OpenCodeWatcher {
|
|
|
156
139
|
if (!partsByMessage.has(part.message_id)) {
|
|
157
140
|
partsByMessage.set(part.message_id, []);
|
|
158
141
|
}
|
|
159
|
-
partsByMessage.get(part.message_id)
|
|
142
|
+
const bucket = partsByMessage.get(part.message_id);
|
|
143
|
+
if (bucket) {
|
|
144
|
+
bucket.push(part);
|
|
145
|
+
}
|
|
160
146
|
}
|
|
161
147
|
|
|
162
148
|
return this.buildMessages(messages, partsByMessage);
|
|
@@ -449,7 +435,10 @@ class OpenCodeWatcher {
|
|
|
449
435
|
if (!partsByMessage.has(part.message_id)) {
|
|
450
436
|
partsByMessage.set(part.message_id, []);
|
|
451
437
|
}
|
|
452
|
-
partsByMessage.get(part.message_id)
|
|
438
|
+
const bucket = partsByMessage.get(part.message_id);
|
|
439
|
+
if (bucket) {
|
|
440
|
+
bucket.push(part);
|
|
441
|
+
}
|
|
453
442
|
}
|
|
454
443
|
|
|
455
444
|
const newEntries = this.buildMessages(dedupedMessages, partsByMessage);
|
|
@@ -510,7 +499,10 @@ class OpenCodeWatcher {
|
|
|
510
499
|
if (!partsByMessage.has(part.message_id)) {
|
|
511
500
|
partsByMessage.set(part.message_id, []);
|
|
512
501
|
}
|
|
513
|
-
partsByMessage.get(part.message_id)
|
|
502
|
+
const bucket = partsByMessage.get(part.message_id);
|
|
503
|
+
if (bucket) {
|
|
504
|
+
bucket.push(part);
|
|
505
|
+
}
|
|
514
506
|
}
|
|
515
507
|
|
|
516
508
|
// Fetch the parent messages for context (batched to avoid SQLite param limit).
|
|
@@ -1,4 +1,9 @@
|
|
|
1
|
-
import type {
|
|
1
|
+
import type {
|
|
2
|
+
ConversationMessage,
|
|
3
|
+
PtyManagedTerminal as ManagedTerminal,
|
|
4
|
+
PtyOutputBuffer as OutputBuffer,
|
|
5
|
+
TerminalRecord,
|
|
6
|
+
} from '$lib/types';
|
|
2
7
|
import type WebSocket from 'ws';
|
|
3
8
|
|
|
4
9
|
import { type ChildProcess, fork } from 'child_process';
|
|
@@ -7,48 +12,11 @@ import { existsSync, readdirSync, readFileSync, statSync, unlinkSync } from 'fs'
|
|
|
7
12
|
import path from 'path';
|
|
8
13
|
import { fileURLToPath } from 'url';
|
|
9
14
|
|
|
10
|
-
import
|
|
11
|
-
|
|
15
|
+
import { broadcastEvent } from '../ws/server.js';
|
|
12
16
|
import { HolderClient } from './holder-client';
|
|
13
17
|
import { openCodeWatcher } from './opencode-watcher';
|
|
14
18
|
import { terminalStore } from './terminal-store';
|
|
15
19
|
|
|
16
|
-
// ---------------------------------------------------------------------------
|
|
17
|
-
// Types
|
|
18
|
-
// ---------------------------------------------------------------------------
|
|
19
|
-
|
|
20
|
-
interface ManagedTerminal {
|
|
21
|
-
args: string[];
|
|
22
|
-
clients: Set<WebSocket>;
|
|
23
|
-
cols: number;
|
|
24
|
-
command: string;
|
|
25
|
-
createdAt: Date;
|
|
26
|
-
currentCwd: null | string;
|
|
27
|
-
cwd: string;
|
|
28
|
-
exitCode: null | number;
|
|
29
|
-
exitedAt: Date | null;
|
|
30
|
-
holderPid: number;
|
|
31
|
-
id: string;
|
|
32
|
-
isActive: boolean;
|
|
33
|
-
openCodeNoopCb: ((messages: ConversationMessage[]) => void) | null;
|
|
34
|
-
openCodeSessionId: null | string;
|
|
35
|
-
outputBuffers: Map<WebSocket, OutputBuffer>;
|
|
36
|
-
pid: number;
|
|
37
|
-
pollTimer: null | ReturnType<typeof setInterval>;
|
|
38
|
-
pty: HolderClient;
|
|
39
|
-
rows: number;
|
|
40
|
-
scrollback: string;
|
|
41
|
-
sessionFile: null | string;
|
|
42
|
-
socketPath: string;
|
|
43
|
-
status: 'exited' | 'running';
|
|
44
|
-
watcherOffset: number;
|
|
45
|
-
}
|
|
46
|
-
|
|
47
|
-
interface OutputBuffer {
|
|
48
|
-
data: string[];
|
|
49
|
-
size: number;
|
|
50
|
-
}
|
|
51
|
-
|
|
52
20
|
export type { ManagedTerminal };
|
|
53
21
|
|
|
54
22
|
// ---------------------------------------------------------------------------
|
|
@@ -195,7 +163,10 @@ class PtyManager {
|
|
|
195
163
|
});
|
|
196
164
|
});
|
|
197
165
|
|
|
198
|
-
|
|
166
|
+
if (holder.pid === undefined || holder.pid === null) {
|
|
167
|
+
throw new Error(`Holder process forked but PID unavailable for terminal ${id}`);
|
|
168
|
+
}
|
|
169
|
+
const holderPid = holder.pid;
|
|
199
170
|
|
|
200
171
|
// Connect to the holder via Unix socket
|
|
201
172
|
const client = new HolderClient();
|
|
@@ -255,6 +226,13 @@ class PtyManager {
|
|
|
255
226
|
this.startSessionDiscovery(terminal);
|
|
256
227
|
|
|
257
228
|
this.terminals.set(id, terminal);
|
|
229
|
+
|
|
230
|
+
broadcastEvent({
|
|
231
|
+
command: terminal.command ?? command,
|
|
232
|
+
terminalId: id,
|
|
233
|
+
type: 'terminal-created',
|
|
234
|
+
});
|
|
235
|
+
|
|
258
236
|
return terminal;
|
|
259
237
|
}
|
|
260
238
|
|
|
@@ -281,11 +259,14 @@ class PtyManager {
|
|
|
281
259
|
} catch {
|
|
282
260
|
// Best effort
|
|
283
261
|
}
|
|
284
|
-
// Also kill the holder process directly
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
262
|
+
// Also kill the holder process directly (guard against invalid PIDs —
|
|
263
|
+
// process.kill(0) targets the current process group, -1 targets all)
|
|
264
|
+
if (terminal.holderPid > 0) {
|
|
265
|
+
try {
|
|
266
|
+
process.kill(terminal.holderPid, 'SIGKILL');
|
|
267
|
+
} catch {
|
|
268
|
+
// Best effort — holder may already be gone
|
|
269
|
+
}
|
|
289
270
|
}
|
|
290
271
|
}
|
|
291
272
|
|
|
@@ -397,6 +378,7 @@ class PtyManager {
|
|
|
397
378
|
terminal.status = 'exited';
|
|
398
379
|
terminal.exitedAt = new Date();
|
|
399
380
|
terminalStore.markExited(id, null);
|
|
381
|
+
this.emitTerminalExited(id, null);
|
|
400
382
|
return true;
|
|
401
383
|
}
|
|
402
384
|
|
|
@@ -411,6 +393,7 @@ class PtyManager {
|
|
|
411
393
|
terminal.status = 'exited';
|
|
412
394
|
terminal.exitedAt = terminal.exitedAt ?? new Date();
|
|
413
395
|
terminalStore.markExited(id, null);
|
|
396
|
+
this.emitTerminalExited(id, null);
|
|
414
397
|
}
|
|
415
398
|
}, SIGKILL_DELAY_MS);
|
|
416
399
|
|
|
@@ -577,6 +560,15 @@ class PtyManager {
|
|
|
577
560
|
// Private: startSessionDiscovery — polling for session files
|
|
578
561
|
// -----------------------------------------------------------------------
|
|
579
562
|
|
|
563
|
+
/** Broadcast a terminal-exited event to /ws/events for the activity feed. */
|
|
564
|
+
private emitTerminalExited(terminalId: string, exitCode: null | number): void {
|
|
565
|
+
broadcastEvent({
|
|
566
|
+
code: exitCode ?? null,
|
|
567
|
+
terminalId,
|
|
568
|
+
type: 'terminal-exited',
|
|
569
|
+
});
|
|
570
|
+
}
|
|
571
|
+
|
|
580
572
|
/** Evict a terminal, freeing all resources. */
|
|
581
573
|
private evict(id: string): void {
|
|
582
574
|
const terminal = this.terminals.get(id);
|
|
@@ -1003,6 +995,8 @@ class PtyManager {
|
|
|
1003
995
|
terminal.exitedAt = new Date();
|
|
1004
996
|
terminalStore.markExited(terminal.id, exitCode);
|
|
1005
997
|
|
|
998
|
+
this.emitTerminalExited(terminal.id, exitCode);
|
|
999
|
+
|
|
1006
1000
|
const exitMsg = JSON.stringify({
|
|
1007
1001
|
code: exitCode,
|
|
1008
1002
|
signal: null,
|
|
@@ -1019,6 +1013,7 @@ class PtyManager {
|
|
|
1019
1013
|
terminal.status = 'exited';
|
|
1020
1014
|
terminal.exitedAt = new Date();
|
|
1021
1015
|
terminalStore.markOrphaned(terminal.id);
|
|
1016
|
+
this.emitTerminalExited(terminal.id, null);
|
|
1022
1017
|
}
|
|
1023
1018
|
});
|
|
1024
1019
|
}
|
|
@@ -1,23 +1,16 @@
|
|
|
1
|
-
import
|
|
1
|
+
import type {
|
|
2
|
+
ConversationMessage,
|
|
3
|
+
MessagePart,
|
|
4
|
+
OnNewEntries,
|
|
5
|
+
SessionWatchedFile as WatchedFile,
|
|
6
|
+
} from '$lib/types';
|
|
7
|
+
|
|
8
|
+
import { watch as chokidarWatch } from 'chokidar';
|
|
2
9
|
import * as fs from 'fs';
|
|
3
10
|
import * as path from 'path';
|
|
4
11
|
|
|
5
|
-
import type { ConversationMessage, MessagePart } from '../sessions/types';
|
|
6
|
-
|
|
7
12
|
import { parseJsonlText } from '../sessions/jsonl-parser';
|
|
8
13
|
|
|
9
|
-
/**
|
|
10
|
-
* Callback invoked when new JSONL entries are parsed from a watched file.
|
|
11
|
-
*/
|
|
12
|
-
type OnNewEntries = (entries: ConversationMessage[]) => void;
|
|
13
|
-
|
|
14
|
-
interface WatchedFile {
|
|
15
|
-
callbacks: Set<OnNewEntries>;
|
|
16
|
-
filePath: string;
|
|
17
|
-
offset: number;
|
|
18
|
-
watcher: FSWatcher;
|
|
19
|
-
}
|
|
20
|
-
|
|
21
14
|
// Path to Claude Code's project session data
|
|
22
15
|
const CLAUDE_PROJECTS_DIR = path.join(process.env.HOME || '', '.claude', 'projects');
|
|
23
16
|
|
|
@@ -89,7 +82,10 @@ class SessionWatcher {
|
|
|
89
82
|
continue;
|
|
90
83
|
}
|
|
91
84
|
try {
|
|
92
|
-
|
|
85
|
+
const parsed: unknown = JSON.parse(trimmed);
|
|
86
|
+
if (typeof parsed === 'object' && parsed !== null && !Array.isArray(parsed)) {
|
|
87
|
+
entries.push(parsed as Record<string, unknown>);
|
|
88
|
+
}
|
|
93
89
|
} catch {
|
|
94
90
|
// skip malformed lines
|
|
95
91
|
}
|
|
@@ -274,7 +270,9 @@ class SessionWatcher {
|
|
|
274
270
|
}
|
|
275
271
|
|
|
276
272
|
// Parse the new lines using the file's accumulated assistant turn state
|
|
277
|
-
const assistantTurns
|
|
273
|
+
const assistantTurns: Map<string, { parts: MessagePart[]; timestamp: string }> =
|
|
274
|
+
this.assistantTurnsPerFile.get(filePath) ??
|
|
275
|
+
new Map<string, { parts: MessagePart[]; timestamp: string }>();
|
|
278
276
|
const startIndex = this.messageIndexPerFile.get(filePath) || 0;
|
|
279
277
|
const newText = completeLines.join('\n');
|
|
280
278
|
const newMessages = parseJsonlText(newText, assistantTurns, startIndex);
|
|
@@ -2,24 +2,9 @@
|
|
|
2
2
|
// Manages the /ws/events channel: tracks connected clients and broadcasts
|
|
3
3
|
// ShooterEvents to all listeners. No client-to-server messages are expected.
|
|
4
4
|
|
|
5
|
-
import type {
|
|
5
|
+
import type { WireShooterEvent as ShooterEvent } from '$lib/types';
|
|
6
6
|
import type { WebSocket } from 'ws';
|
|
7
7
|
|
|
8
|
-
// ── Event types ─────────────────────────────────────────────────────
|
|
9
|
-
|
|
10
|
-
export type ShooterEvent =
|
|
11
|
-
| { code: null | number; terminalId: string; type: 'terminal-exited' }
|
|
12
|
-
| { command: string; terminalId: string; type: 'terminal-created' }
|
|
13
|
-
| { decision: PermissionDecision; requestId: string; type: 'permission-resolved' }
|
|
14
|
-
| {
|
|
15
|
-
input: Record<string, unknown>;
|
|
16
|
-
requestId: string;
|
|
17
|
-
tool: string;
|
|
18
|
-
type: 'permission-requested';
|
|
19
|
-
}
|
|
20
|
-
| { project: string; sessionId: string; source: SessionSource; type: 'session-started' }
|
|
21
|
-
| { sessionId: string; summary: string; type: 'session-ended' };
|
|
22
|
-
|
|
23
8
|
// ── Connection tracking ─────────────────────────────────────────────
|
|
24
9
|
|
|
25
10
|
/** All clients subscribed to the global events channel. */
|
|
@@ -6,6 +6,7 @@
|
|
|
6
6
|
// Cloudflare Tunnel closes idle WebSocket connections after ~100 seconds,
|
|
7
7
|
// so 30-second pings keep connections alive through the tunnel.
|
|
8
8
|
|
|
9
|
+
import type { PendingPong } from '$lib/types';
|
|
9
10
|
import type { WebSocket } from 'ws';
|
|
10
11
|
|
|
11
12
|
import { getAllConnections } from './server.js';
|
|
@@ -24,11 +25,6 @@ let pingInterval: null | ReturnType<typeof setInterval> = null;
|
|
|
24
25
|
* Stores the timeout timer and the listener functions so they can be
|
|
25
26
|
* removed cleanly when stopKeepalive() is called mid-cycle.
|
|
26
27
|
*/
|
|
27
|
-
interface PendingPong {
|
|
28
|
-
onClose: () => void;
|
|
29
|
-
onPong: () => void;
|
|
30
|
-
timer: ReturnType<typeof setTimeout>;
|
|
31
|
-
}
|
|
32
28
|
const pendingPongs = new Map<WebSocket, PendingPong>();
|
|
33
29
|
|
|
34
30
|
// ── Public API ───────────────────────────────────────────────────────
|
|
@@ -16,7 +16,7 @@ import {
|
|
|
16
16
|
} from './events-handler.js';
|
|
17
17
|
import { handleSessionConnection } from './session-handler.js';
|
|
18
18
|
import { handleTerminalConnection } from './terminal-handler.js';
|
|
19
|
-
export type { ShooterEvent } from '
|
|
19
|
+
export type { WireShooterEvent as ShooterEvent } from '$lib/types';
|
|
20
20
|
|
|
21
21
|
// ── Connection tracking ──────────────────────────────────────────────
|
|
22
22
|
|
|
@@ -3,98 +3,31 @@
|
|
|
3
3
|
// on connect and streams new messages (text, tool-use, tool-result,
|
|
4
4
|
// thinking) as they appear.
|
|
5
5
|
|
|
6
|
-
import type {
|
|
6
|
+
import type {
|
|
7
|
+
WireSessionClientMessage as ClientMessage,
|
|
8
|
+
WsConnectionState as ConnectionState,
|
|
9
|
+
ConversationMessage,
|
|
10
|
+
WireHistoryMessage as HistoryMessage,
|
|
11
|
+
WireHistoryPart as HistoryPart,
|
|
12
|
+
SessionManagedTerminal as ManagedTerminal,
|
|
13
|
+
MessagePart,
|
|
14
|
+
SessionPtyManagerFullLike as PtyManagerFullLike,
|
|
15
|
+
SessionPtyManagerLike as PtyManagerLike,
|
|
16
|
+
WireSessionServerMessage as ServerMessage,
|
|
17
|
+
SessionWatcherLike,
|
|
18
|
+
TextContentBlock,
|
|
19
|
+
} from '$lib/types';
|
|
7
20
|
import type { WebSocket } from 'ws';
|
|
8
21
|
|
|
9
22
|
import * as fs from 'fs';
|
|
10
23
|
import * as path from 'path';
|
|
11
24
|
|
|
12
|
-
import type { ConversationMessage, MessagePart } from '../sessions/types';
|
|
13
|
-
|
|
14
|
-
// ── Types ────────────────────────────────────────────────────────────
|
|
15
|
-
|
|
16
|
-
/** Inbound messages from the client. */
|
|
17
|
-
type ClientMessage =
|
|
18
|
-
| { sessionId: string; type: 'subscribe' }
|
|
19
|
-
| { text: string; type: 'send-input' }
|
|
20
|
-
| { type: 'cancel' };
|
|
21
|
-
|
|
22
|
-
/** A message in the history payload. */
|
|
23
|
-
interface HistoryMessage {
|
|
24
|
-
content: HistoryPart[];
|
|
25
|
-
id: string;
|
|
26
|
-
role: MessageRole;
|
|
27
|
-
timestamp: string;
|
|
28
|
-
}
|
|
29
|
-
|
|
30
|
-
/** A single part within a history message — discriminated union. */
|
|
31
|
-
type HistoryPart =
|
|
32
|
-
| { content: string; type: 'text' }
|
|
33
|
-
| { content: string; type: 'thinking' }
|
|
34
|
-
| { id: string; input: Record<string, unknown>; toolName: string; type: 'tool_use' }
|
|
35
|
-
| { isError: boolean; output: string; toolUseId: string; type: 'tool_result' };
|
|
36
|
-
|
|
37
|
-
interface ManagedTerminal {
|
|
38
|
-
id: string;
|
|
39
|
-
openCodeSessionId: null | string;
|
|
40
|
-
pty: {
|
|
41
|
-
pid: number;
|
|
42
|
-
write: (data: string) => void;
|
|
43
|
-
};
|
|
44
|
-
sessionFile: null | string;
|
|
45
|
-
status: 'exited' | 'running';
|
|
46
|
-
}
|
|
47
|
-
|
|
48
|
-
/** Extended PTY manager interface with list() for UUID-based terminal search. */
|
|
49
|
-
interface PtyManagerFullLike extends PtyManagerLike {
|
|
50
|
-
list: () => ManagedTerminal[];
|
|
51
|
-
}
|
|
52
|
-
|
|
53
|
-
interface PtyManagerLike {
|
|
54
|
-
getTerminal: (id: string) => ManagedTerminal | undefined;
|
|
55
|
-
}
|
|
56
|
-
|
|
57
|
-
// ── PTY Manager type ─────────────────────────────────────────────────
|
|
58
|
-
|
|
59
|
-
/** Outbound messages to the client. */
|
|
60
|
-
type ServerMessage =
|
|
61
|
-
| { content: TextContentBlock[]; role: MessageRole; timestamp: string; type: 'message' }
|
|
62
|
-
| {
|
|
63
|
-
id: string;
|
|
64
|
-
input: Record<string, unknown>;
|
|
65
|
-
name: string;
|
|
66
|
-
status: 'running';
|
|
67
|
-
type: 'tool-use';
|
|
68
|
-
}
|
|
69
|
-
| { id: string; isError: boolean; output: string; status: 'done'; type: 'tool-result' }
|
|
70
|
-
| { message: string; type: 'error' }
|
|
71
|
-
| { messages: HistoryMessage[]; type: 'history' }
|
|
72
|
-
| { text: string; type: 'thinking' }
|
|
73
|
-
| { type: 'session-end' };
|
|
74
|
-
|
|
75
|
-
interface SessionWatcherLike {
|
|
76
|
-
getHistory: (sessionFile: string) => ConversationMessage[];
|
|
77
|
-
subscribe: (
|
|
78
|
-
sessionFile: string,
|
|
79
|
-
callback: (messages: ConversationMessage[]) => void
|
|
80
|
-
) => () => void;
|
|
81
|
-
}
|
|
82
|
-
|
|
83
25
|
// ── Module-level references ──────────────────────────────────────────
|
|
84
26
|
|
|
85
27
|
let _ptyManager: null | PtyManagerLike = null;
|
|
86
28
|
let _ptyManagerFull: null | PtyManagerFullLike = null;
|
|
87
29
|
let _sessionWatcher: null | SessionWatcherLike = null;
|
|
88
30
|
|
|
89
|
-
/** Per-connection state tracked for cleanup. */
|
|
90
|
-
interface ConnectionState {
|
|
91
|
-
/** True when the session is file-only (no terminal backing it). */
|
|
92
|
-
isExternalSession: boolean;
|
|
93
|
-
retryInterval: null | ReturnType<typeof setInterval>;
|
|
94
|
-
terminalId: string;
|
|
95
|
-
unsubscribe: (() => void) | null;
|
|
96
|
-
}
|
|
97
|
-
|
|
98
31
|
/**
|
|
99
32
|
* Handle a new WebSocket connection on the `/ws/session/:id` channel.
|
|
100
33
|
* Accepts BOTH Shooter terminal IDs and external Claude Code session UUIDs.
|
|
@@ -285,7 +218,7 @@ function findTerminalBySessionUuid(uuid: string): ManagedTerminal | undefined {
|
|
|
285
218
|
// module-level _ptyManagerFull reference if available.
|
|
286
219
|
if (_ptyManagerFull) {
|
|
287
220
|
for (const t of _ptyManagerFull.list()) {
|
|
288
|
-
if (t.sessionFile
|
|
221
|
+
if (t.sessionFile?.includes(`${uuid}.jsonl`)) {
|
|
289
222
|
return _ptyManager.getTerminal(t.id);
|
|
290
223
|
}
|
|
291
224
|
}
|
|
@@ -296,7 +229,7 @@ function findTerminalBySessionUuid(uuid: string): ManagedTerminal | undefined {
|
|
|
296
229
|
/** Parse and validate an inbound client message. */
|
|
297
230
|
function parseClientMessage(raw: string): ClientMessage | null {
|
|
298
231
|
try {
|
|
299
|
-
const msg = JSON.parse(raw)
|
|
232
|
+
const msg = JSON.parse(raw) as Record<string, unknown>;
|
|
300
233
|
if (!msg || typeof msg !== 'object' || typeof msg.type !== 'string') {
|
|
301
234
|
return null;
|
|
302
235
|
}
|
|
@@ -589,7 +522,8 @@ function wireClientMessages(ws: WebSocket, state: ConnectionState): void {
|
|
|
589
522
|
case 'send-input': {
|
|
590
523
|
if (state.isExternalSession) {
|
|
591
524
|
safeSend(ws, {
|
|
592
|
-
message:
|
|
525
|
+
message:
|
|
526
|
+
'Cannot send input — this is a read-only session. Connect to a terminal first.',
|
|
593
527
|
type: 'error',
|
|
594
528
|
});
|
|
595
529
|
return;
|
|
@@ -615,8 +549,8 @@ function wireClientMessages(ws: WebSocket, state: ConnectionState): void {
|
|
|
615
549
|
}
|
|
616
550
|
|
|
617
551
|
// Try terminal first, then external
|
|
618
|
-
const newTerminal =
|
|
619
|
-
?? findTerminalBySessionUuid(msg.sessionId);
|
|
552
|
+
const newTerminal =
|
|
553
|
+
_ptyManager?.getTerminal(msg.sessionId) ?? findTerminalBySessionUuid(msg.sessionId);
|
|
620
554
|
|
|
621
555
|
if (newTerminal) {
|
|
622
556
|
state.terminalId = newTerminal.id;
|
|
@@ -2,25 +2,14 @@
|
|
|
2
2
|
// Relays terminal output to connected clients and routes client input
|
|
3
3
|
// (keystrokes, resize, signals) back to the PTY.
|
|
4
4
|
|
|
5
|
-
import type {
|
|
5
|
+
import type {
|
|
6
|
+
WireTerminalClientMessage as ClientMessage,
|
|
7
|
+
TerminalPtyManagerLike as PtyManagerLike,
|
|
8
|
+
WireTerminalServerMessage as ServerMessage,
|
|
9
|
+
TerminalSignal,
|
|
10
|
+
} from '$lib/types';
|
|
6
11
|
import type { WebSocket } from 'ws';
|
|
7
12
|
|
|
8
|
-
// ── Types ────────────────────────────────────────────────────────────
|
|
9
|
-
|
|
10
|
-
/** Inbound messages from the client. */
|
|
11
|
-
type ClientMessage =
|
|
12
|
-
| { cols: number; rows: number; type: 'resize' }
|
|
13
|
-
| { data: string; type: 'input' }
|
|
14
|
-
| { signal: TerminalSignal; type: 'signal' };
|
|
15
|
-
|
|
16
|
-
/** Outbound messages to the client. */
|
|
17
|
-
type ServerMessage =
|
|
18
|
-
| { bytes: number; type: 'output-dropped' }
|
|
19
|
-
| { chunk: number; data: string; total: number; type: 'scrollback' }
|
|
20
|
-
| { code: null | number; signal: null | string; type: 'exit' }
|
|
21
|
-
| { data: string; type: 'output' }
|
|
22
|
-
| { message: string; type: 'error' };
|
|
23
|
-
|
|
24
13
|
// ── Constants ────────────────────────────────────────────────────────
|
|
25
14
|
|
|
26
15
|
/** Signal name → numeric code for process.kill(). */
|
|
@@ -30,28 +19,6 @@ const SIGNAL_MAP: Record<string, NodeJS.Signals> = {
|
|
|
30
19
|
SIGTSTP: 'SIGTSTP',
|
|
31
20
|
};
|
|
32
21
|
|
|
33
|
-
// ── PTY Manager type ─────────────────────────────────────────────────
|
|
34
|
-
// Minimal duck-typed shape matching the real pty-manager singleton.
|
|
35
|
-
|
|
36
|
-
interface ManagedTerminal {
|
|
37
|
-
clients: Set<WebSocket>;
|
|
38
|
-
exitCode: null | number;
|
|
39
|
-
id: string;
|
|
40
|
-
pty: {
|
|
41
|
-
kill: (signal: string) => void;
|
|
42
|
-
pid: number;
|
|
43
|
-
resize: (cols: number, rows: number) => void;
|
|
44
|
-
write: (data: string) => void;
|
|
45
|
-
};
|
|
46
|
-
status: 'exited' | 'running';
|
|
47
|
-
}
|
|
48
|
-
|
|
49
|
-
interface PtyManagerLike {
|
|
50
|
-
attach: (id: string, ws: WebSocket) => boolean;
|
|
51
|
-
detach: (id: string, ws: WebSocket) => boolean;
|
|
52
|
-
getTerminal: (id: string) => ManagedTerminal | undefined;
|
|
53
|
-
}
|
|
54
|
-
|
|
55
22
|
// Placeholder: will be replaced with the real ptyManager singleton import.
|
|
56
23
|
// import { ptyManager } from '../terminal/pty-manager';
|
|
57
24
|
let _ptyManager: null | PtyManagerLike = null;
|
|
@@ -153,8 +120,13 @@ export function setPtyManager(manager: PtyManagerLike): void {
|
|
|
153
120
|
/** Parse and validate an inbound client message. Returns null for invalid messages. */
|
|
154
121
|
function parseClientMessage(raw: string): ClientMessage | null {
|
|
155
122
|
try {
|
|
156
|
-
const
|
|
157
|
-
if (!
|
|
123
|
+
const parsed: unknown = JSON.parse(raw);
|
|
124
|
+
if (!parsed || typeof parsed !== 'object') {
|
|
125
|
+
return null;
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
const msg = parsed as Record<string, unknown>;
|
|
129
|
+
if (typeof msg.type !== 'string') {
|
|
158
130
|
return null;
|
|
159
131
|
}
|
|
160
132
|
|
|
@@ -164,27 +136,32 @@ function parseClientMessage(raw: string): ClientMessage | null {
|
|
|
164
136
|
return null;
|
|
165
137
|
}
|
|
166
138
|
return { data: msg.data, type: 'input' };
|
|
167
|
-
case 'resize':
|
|
139
|
+
case 'resize': {
|
|
140
|
+
const cols = msg.cols;
|
|
141
|
+
const rows = msg.rows;
|
|
168
142
|
if (
|
|
169
|
-
typeof
|
|
170
|
-
typeof
|
|
171
|
-
!Number.isFinite(
|
|
172
|
-
!Number.isFinite(
|
|
143
|
+
typeof cols !== 'number' ||
|
|
144
|
+
typeof rows !== 'number' ||
|
|
145
|
+
!Number.isFinite(cols) ||
|
|
146
|
+
!Number.isFinite(rows)
|
|
173
147
|
) {
|
|
174
148
|
return null;
|
|
175
149
|
}
|
|
176
|
-
if (
|
|
150
|
+
if (cols < 1 || rows < 1 || cols > 500 || rows > 200) {
|
|
177
151
|
return null;
|
|
178
152
|
}
|
|
179
|
-
return { cols: Math.floor(
|
|
180
|
-
|
|
181
|
-
|
|
153
|
+
return { cols: Math.floor(cols), rows: Math.floor(rows), type: 'resize' };
|
|
154
|
+
}
|
|
155
|
+
case 'signal': {
|
|
156
|
+
const signal = msg.signal;
|
|
157
|
+
if (typeof signal !== 'string' || !Object.hasOwn(SIGNAL_MAP, signal)) {
|
|
182
158
|
return null;
|
|
183
159
|
}
|
|
184
160
|
return {
|
|
185
|
-
signal:
|
|
161
|
+
signal: signal as TerminalSignal,
|
|
186
162
|
type: 'signal',
|
|
187
163
|
};
|
|
164
|
+
}
|
|
188
165
|
default:
|
|
189
166
|
return null;
|
|
190
167
|
}
|
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
// This avoids putting the long-lived API_KEY in WebSocket URL query parameters,
|
|
6
6
|
// which would appear in proxy logs, Cloudflare access logs, and browser history.
|
|
7
7
|
|
|
8
|
-
import type { Ticket } from '$
|
|
8
|
+
import type { Ticket } from '$lib/types';
|
|
9
9
|
|
|
10
10
|
import { randomBytes } from 'crypto';
|
|
11
11
|
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import type { ProviderId } from '$lib/types';
|
|
2
|
+
|
|
3
|
+
/** Env key names required for each provider to be considered configured. */
|
|
4
|
+
export const PROVIDER_ENV_KEYS: Record<ProviderId, string[]> = {
|
|
5
|
+
anthropic: ['ANTHROPIC_API_KEY'],
|
|
6
|
+
'google-ai': ['GOOGLE_AI_API_KEY'],
|
|
7
|
+
litellm: ['LITELLM_API_KEY', 'LITELLM_BASE_URL'],
|
|
8
|
+
mistral: ['MISTRAL_API_KEY'],
|
|
9
|
+
openai: ['OPENAI_API_KEY'],
|
|
10
|
+
};
|
|
11
|
+
|
|
12
|
+
/** Check which providers have credentials configured. */
|
|
13
|
+
export function getProviderAvailability(
|
|
14
|
+
env: Record<string, string | undefined>
|
|
15
|
+
): Record<ProviderId, boolean> {
|
|
16
|
+
const result = {} as Record<ProviderId, boolean>;
|
|
17
|
+
for (const [id, keys] of Object.entries(PROVIDER_ENV_KEYS)) {
|
|
18
|
+
result[id as ProviderId] = keys.every((k) => Boolean(env[k]?.trim()));
|
|
19
|
+
}
|
|
20
|
+
return result;
|
|
21
|
+
}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
// Activity feed types that require union types not expressible in type-crafter YAML.
|
|
2
|
+
|
|
3
|
+
/** A single content block within a WebSocket session message. */
|
|
4
|
+
export interface ActivityContentBlock {
|
|
5
|
+
content?: string;
|
|
6
|
+
is_error?: boolean;
|
|
7
|
+
name?: string;
|
|
8
|
+
text?: string;
|
|
9
|
+
type: string;
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
/** A conversation message from a Claude Code session history batch.
|
|
13
|
+
* Uses a union type (string | array) which the YAML schema cannot express. */
|
|
14
|
+
export interface ActivitySessionMessage {
|
|
15
|
+
content: ActivityContentBlock[] | string;
|
|
16
|
+
role: string;
|
|
17
|
+
timestamp?: string;
|
|
18
|
+
}
|