@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
|
@@ -0,0 +1,136 @@
|
|
|
1
|
+
// Server-side proxy for AI providers that block direct browser requests (CORS).
|
|
2
|
+
// The browser NeuroLink bundle POSTs here; this endpoint forwards to the real API.
|
|
3
|
+
// Currently supports: anthropic (api.anthropic.com blocks browser fetch).
|
|
4
|
+
|
|
5
|
+
import { env } from '$env/dynamic/private';
|
|
6
|
+
import { validateAuth } from '$lib/modules/server/auth';
|
|
7
|
+
import { json } from '@sveltejs/kit';
|
|
8
|
+
|
|
9
|
+
import type { RequestHandler } from './$types';
|
|
10
|
+
|
|
11
|
+
// Per-provider allowlist of client-supplied headers that may be forwarded
|
|
12
|
+
// upstream. Everything else (including host, x-forwarded-*, content-type) is
|
|
13
|
+
// dropped so the browser can't influence provider behavior beyond what we
|
|
14
|
+
// explicitly permit.
|
|
15
|
+
const ALLOWED_CLIENT_HEADERS: Record<string, Set<string>> = {
|
|
16
|
+
anthropic: new Set(['anthropic-beta', 'anthropic-version']),
|
|
17
|
+
'google-ai': new Set<string>([]),
|
|
18
|
+
mistral: new Set([]),
|
|
19
|
+
openai: new Set(['openai-organization', 'openai-project']),
|
|
20
|
+
};
|
|
21
|
+
|
|
22
|
+
export const POST: RequestHandler = async ({ request }) => {
|
|
23
|
+
const authError = validateAuth(request);
|
|
24
|
+
if (authError) {
|
|
25
|
+
return authError;
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
let payload: unknown;
|
|
29
|
+
try {
|
|
30
|
+
payload = await request.json();
|
|
31
|
+
} catch {
|
|
32
|
+
return json({ error: 'Invalid JSON body' }, { status: 400 });
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
if (
|
|
36
|
+
!payload ||
|
|
37
|
+
typeof payload !== 'object' ||
|
|
38
|
+
typeof (payload as { provider?: unknown }).provider !== 'string' ||
|
|
39
|
+
typeof (payload as { url?: unknown }).url !== 'string' ||
|
|
40
|
+
!(payload as { headers?: unknown }).headers ||
|
|
41
|
+
typeof (payload as { headers?: unknown }).headers !== 'object'
|
|
42
|
+
) {
|
|
43
|
+
return json({ error: 'Invalid proxy payload' }, { status: 400 });
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
const {
|
|
47
|
+
body,
|
|
48
|
+
headers: reqHeaders,
|
|
49
|
+
provider,
|
|
50
|
+
url,
|
|
51
|
+
} = payload as {
|
|
52
|
+
body: unknown;
|
|
53
|
+
headers: Record<string, string>;
|
|
54
|
+
provider: string;
|
|
55
|
+
url: string;
|
|
56
|
+
};
|
|
57
|
+
|
|
58
|
+
// Only proxy known safe providers — never forward arbitrary URLs
|
|
59
|
+
const ALLOWED_PREFIXES: Record<string, string> = {
|
|
60
|
+
anthropic: 'https://api.anthropic.com/',
|
|
61
|
+
'google-ai': 'https://generativelanguage.googleapis.com/',
|
|
62
|
+
mistral: 'https://api.mistral.ai/',
|
|
63
|
+
openai: 'https://api.openai.com/',
|
|
64
|
+
};
|
|
65
|
+
|
|
66
|
+
const allowedPrefix = ALLOWED_PREFIXES[provider];
|
|
67
|
+
if (!allowedPrefix || !url.startsWith(allowedPrefix)) {
|
|
68
|
+
return json({ error: `Provider "${provider}" or URL not allowed` }, { status: 403 });
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
// Inject the server-side API key so the browser never sees it
|
|
72
|
+
const apiKeyEnv: Record<string, string> = {
|
|
73
|
+
anthropic: env.ANTHROPIC_API_KEY ?? '',
|
|
74
|
+
'google-ai': env.GOOGLE_AI_API_KEY ?? '',
|
|
75
|
+
mistral: env.MISTRAL_API_KEY ?? '',
|
|
76
|
+
openai: env.OPENAI_API_KEY ?? '',
|
|
77
|
+
};
|
|
78
|
+
|
|
79
|
+
// Copy only explicitly-allowed headers per provider. Everything else is
|
|
80
|
+
// dropped so the browser can't influence upstream behavior via host,
|
|
81
|
+
// x-forwarded-*, organization selectors, provider feature toggles, etc.
|
|
82
|
+
const allowedForProvider = ALLOWED_CLIENT_HEADERS[provider] ?? new Set<string>();
|
|
83
|
+
const normalizedReqHeaders: Record<string, string> = {};
|
|
84
|
+
for (const [k, v] of Object.entries(reqHeaders)) {
|
|
85
|
+
const key = k.toLowerCase();
|
|
86
|
+
if (allowedForProvider.has(key)) {
|
|
87
|
+
normalizedReqHeaders[key] = v;
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
const forwardHeaders: Record<string, string> = {
|
|
92
|
+
'Content-Type': 'application/json',
|
|
93
|
+
...normalizedReqHeaders,
|
|
94
|
+
};
|
|
95
|
+
|
|
96
|
+
// Override / set auth header with server-side key
|
|
97
|
+
if (provider === 'anthropic') {
|
|
98
|
+
forwardHeaders['x-api-key'] = apiKeyEnv.anthropic;
|
|
99
|
+
forwardHeaders['anthropic-version'] = forwardHeaders['anthropic-version'] ?? '2023-06-01';
|
|
100
|
+
} else if (provider === 'google-ai') {
|
|
101
|
+
forwardHeaders['x-goog-api-key'] = apiKeyEnv['google-ai'];
|
|
102
|
+
} else if (provider === 'openai') {
|
|
103
|
+
forwardHeaders.Authorization = `Bearer ${apiKeyEnv.openai}`;
|
|
104
|
+
} else if (provider === 'mistral') {
|
|
105
|
+
forwardHeaders.Authorization = `Bearer ${apiKeyEnv.mistral}`;
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
const controller = new AbortController();
|
|
109
|
+
const timeout = setTimeout(() => {
|
|
110
|
+
controller.abort();
|
|
111
|
+
}, 30_000);
|
|
112
|
+
|
|
113
|
+
let resp: Response;
|
|
114
|
+
try {
|
|
115
|
+
resp = await fetch(url, {
|
|
116
|
+
body: JSON.stringify(body),
|
|
117
|
+
headers: forwardHeaders,
|
|
118
|
+
method: 'POST',
|
|
119
|
+
signal: controller.signal,
|
|
120
|
+
});
|
|
121
|
+
} catch (err) {
|
|
122
|
+
clearTimeout(timeout);
|
|
123
|
+
const message = err instanceof Error ? err.message : 'Upstream request failed';
|
|
124
|
+
return json({ error: message }, { status: 502 });
|
|
125
|
+
}
|
|
126
|
+
clearTimeout(timeout);
|
|
127
|
+
|
|
128
|
+
let data: unknown;
|
|
129
|
+
try {
|
|
130
|
+
data = await resp.json();
|
|
131
|
+
} catch {
|
|
132
|
+
return json({ error: 'Upstream returned non-JSON response' }, { status: 502 });
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
return json(data, { status: resp.status });
|
|
136
|
+
};
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { NotificationData } from '$
|
|
1
|
+
import type { NotificationData } from '$lib/types';
|
|
2
2
|
|
|
3
3
|
import { env } from '$env/dynamic/private';
|
|
4
4
|
import { LibraryAPNsService } from '$lib/modules/server/apn/library-apns';
|
|
@@ -7,10 +7,33 @@ import { createPendingRequest } from '$lib/modules/server/apn/pending-requests';
|
|
|
7
7
|
import { validateAuth } from '$lib/modules/server/auth';
|
|
8
8
|
import { isFCMConfigured, sendFCMNotification } from '$lib/modules/server/fcm/fcm-service.js';
|
|
9
9
|
import { toErrorMessage } from '$lib/modules/server/utils/error';
|
|
10
|
+
import { broadcastEvent } from '$lib/modules/server/ws/server';
|
|
10
11
|
import { json } from '@sveltejs/kit';
|
|
12
|
+
import { existsSync, readFileSync } from 'fs';
|
|
13
|
+
import { homedir } from 'os';
|
|
14
|
+
import { join } from 'path';
|
|
11
15
|
|
|
12
16
|
import type { RequestHandler } from './$types';
|
|
13
17
|
|
|
18
|
+
// Reads tokens persisted by /api/device-token — populated automatically when
|
|
19
|
+
// the Android or iOS app registers on first launch.
|
|
20
|
+
function readPersistedDeviceToken(platform: 'android' | 'ios'): string | undefined {
|
|
21
|
+
const tokensFile = join(homedir(), '.shooter', 'device-tokens.json');
|
|
22
|
+
if (!existsSync(tokensFile)) {
|
|
23
|
+
return undefined;
|
|
24
|
+
}
|
|
25
|
+
try {
|
|
26
|
+
const parsed: unknown = JSON.parse(readFileSync(tokensFile, 'utf-8'));
|
|
27
|
+
if (parsed && typeof parsed === 'object' && !Array.isArray(parsed)) {
|
|
28
|
+
const value = (parsed as Record<string, unknown>)[platform];
|
|
29
|
+
return typeof value === 'string' && value ? value : undefined;
|
|
30
|
+
}
|
|
31
|
+
} catch {
|
|
32
|
+
// corrupt / unreadable — fall through
|
|
33
|
+
}
|
|
34
|
+
return undefined;
|
|
35
|
+
}
|
|
36
|
+
|
|
14
37
|
// Singleton APNs client - reuses HTTP/2 connection across requests
|
|
15
38
|
let apnsSingleton: LibraryAPNsService | null = null;
|
|
16
39
|
function getAPNsClient(): LibraryAPNsService {
|
|
@@ -24,15 +47,118 @@ function getAPNsClient(): LibraryAPNsService {
|
|
|
24
47
|
const notificationCache = new Map<string, number>();
|
|
25
48
|
const DEDUP_WINDOW = 10000; // 10 seconds deduplication window
|
|
26
49
|
|
|
50
|
+
function broadcastHookEvent(body: Record<string, unknown>): void {
|
|
51
|
+
const data = (body.data ?? {}) as Record<string, unknown>;
|
|
52
|
+
const eventType =
|
|
53
|
+
typeof data.eventType === 'string'
|
|
54
|
+
? data.eventType
|
|
55
|
+
: typeof body.eventType === 'string'
|
|
56
|
+
? body.eventType
|
|
57
|
+
: '';
|
|
58
|
+
const tool = typeof data.tool === 'string' ? data.tool : '';
|
|
59
|
+
const terminalId = typeof data.terminalId === 'string' ? data.terminalId : undefined;
|
|
60
|
+
const sessionId = typeof data.sessionId === 'string' ? data.sessionId : undefined;
|
|
61
|
+
|
|
62
|
+
switch (eventType) {
|
|
63
|
+
case 'error':
|
|
64
|
+
broadcastEvent({
|
|
65
|
+
error:
|
|
66
|
+
typeof data.error === 'string'
|
|
67
|
+
? data.error
|
|
68
|
+
: typeof data.message === 'string'
|
|
69
|
+
? data.message
|
|
70
|
+
: 'Unknown error',
|
|
71
|
+
terminalId,
|
|
72
|
+
tool,
|
|
73
|
+
type: 'tool-failed',
|
|
74
|
+
});
|
|
75
|
+
break;
|
|
76
|
+
case 'idle_input':
|
|
77
|
+
case 'session.idle':
|
|
78
|
+
broadcastEvent({
|
|
79
|
+
message: typeof data.message === 'string' ? data.message : '',
|
|
80
|
+
sessionId,
|
|
81
|
+
terminalId,
|
|
82
|
+
type: 'agent-idle',
|
|
83
|
+
});
|
|
84
|
+
break;
|
|
85
|
+
case 'permission':
|
|
86
|
+
case 'permission_notification':
|
|
87
|
+
if (data.requestId && data.toolName) {
|
|
88
|
+
broadcastEvent({
|
|
89
|
+
input:
|
|
90
|
+
typeof data.toolInput === 'object' && data.toolInput !== null
|
|
91
|
+
? (data.toolInput as Record<string, unknown>)
|
|
92
|
+
: {},
|
|
93
|
+
requestId: data.requestId as string,
|
|
94
|
+
tool: data.toolName as string,
|
|
95
|
+
type: 'permission-requested',
|
|
96
|
+
});
|
|
97
|
+
}
|
|
98
|
+
break;
|
|
99
|
+
case 'question':
|
|
100
|
+
broadcastEvent({
|
|
101
|
+
message: typeof data.message === 'string' ? data.message : '',
|
|
102
|
+
sessionId,
|
|
103
|
+
terminalId,
|
|
104
|
+
type: 'agent-question',
|
|
105
|
+
});
|
|
106
|
+
break;
|
|
107
|
+
case 'tool.after':
|
|
108
|
+
broadcastEvent({ success: true, terminalId, tool, type: 'tool-completed' });
|
|
109
|
+
break;
|
|
110
|
+
case 'tool.before':
|
|
111
|
+
broadcastEvent({
|
|
112
|
+
command: typeof data.command === 'string' ? data.command : '',
|
|
113
|
+
filePath:
|
|
114
|
+
typeof data.filePath === 'string'
|
|
115
|
+
? data.filePath
|
|
116
|
+
: typeof data.files === 'string'
|
|
117
|
+
? data.files
|
|
118
|
+
: '',
|
|
119
|
+
terminalId,
|
|
120
|
+
tool,
|
|
121
|
+
type: 'tool-started',
|
|
122
|
+
});
|
|
123
|
+
break;
|
|
124
|
+
// session.status, intervention — skip or use existing types
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
/** Build a notification history record from common fields. */
|
|
129
|
+
function buildNotificationRecord(
|
|
130
|
+
id: string,
|
|
131
|
+
title: string,
|
|
132
|
+
message: string,
|
|
133
|
+
status: 'failed' | 'filtered' | 'sent' | 'skipped',
|
|
134
|
+
data?: NotificationData,
|
|
135
|
+
error?: null | string
|
|
136
|
+
): Parameters<typeof addNotification>[0] {
|
|
137
|
+
return {
|
|
138
|
+
category: data?.category ?? null,
|
|
139
|
+
data: (data as Record<string, unknown>) ?? null,
|
|
140
|
+
error: error ?? null,
|
|
141
|
+
id,
|
|
142
|
+
message,
|
|
143
|
+
project: data?.project ?? null,
|
|
144
|
+
source: data?.source ?? null,
|
|
145
|
+
status,
|
|
146
|
+
timestamp: new Date().toISOString(),
|
|
147
|
+
title,
|
|
148
|
+
tool: data?.tool ?? null,
|
|
149
|
+
};
|
|
150
|
+
}
|
|
151
|
+
|
|
27
152
|
function intelligentNotificationFilter(
|
|
28
153
|
title: string,
|
|
29
154
|
message: string,
|
|
30
|
-
data?: NotificationData
|
|
155
|
+
data?: NotificationData,
|
|
156
|
+
waitForResponse = false
|
|
31
157
|
): { reason: string; send: boolean } {
|
|
32
158
|
const source = data?.source || 'unknown';
|
|
33
159
|
|
|
34
160
|
// Check for duplicate notifications first
|
|
35
|
-
if (isDuplicateNotification(title, message, data)) {
|
|
161
|
+
if (isDuplicateNotification(title, message, data, waitForResponse)) {
|
|
36
162
|
return {
|
|
37
163
|
reason: 'Duplicate notification within 10-second window',
|
|
38
164
|
send: false,
|
|
@@ -100,12 +226,23 @@ function intelligentNotificationFilter(
|
|
|
100
226
|
};
|
|
101
227
|
}
|
|
102
228
|
|
|
103
|
-
function isDuplicateNotification(
|
|
229
|
+
function isDuplicateNotification(
|
|
230
|
+
title: string,
|
|
231
|
+
message: string,
|
|
232
|
+
data?: NotificationData,
|
|
233
|
+
waitForResponse = false
|
|
234
|
+
): boolean {
|
|
235
|
+
// Never deduplicate bidirectional permission requests — each one creates a
|
|
236
|
+
// unique pending request that the hook polls by requestId.
|
|
237
|
+
if (waitForResponse) {
|
|
238
|
+
return false;
|
|
239
|
+
}
|
|
240
|
+
|
|
104
241
|
const key = `${title}|${message}|${data?.category || 'unknown'}`;
|
|
105
242
|
const now = Date.now();
|
|
106
243
|
|
|
107
244
|
if (notificationCache.has(key)) {
|
|
108
|
-
const lastSent = notificationCache.get(key)
|
|
245
|
+
const lastSent = notificationCache.get(key) ?? 0;
|
|
109
246
|
if (now - lastSent < DEDUP_WINDOW) {
|
|
110
247
|
return true; // Duplicate within time window
|
|
111
248
|
}
|
|
@@ -159,6 +296,13 @@ export const POST: RequestHandler = async ({ request }) => {
|
|
|
159
296
|
const waitForResponse =
|
|
160
297
|
typeof body.waitForResponse === 'boolean' ? body.waitForResponse : false;
|
|
161
298
|
|
|
299
|
+
// Broadcast to /ws/events for real-time activity feed
|
|
300
|
+
try {
|
|
301
|
+
broadcastHookEvent(body);
|
|
302
|
+
} catch {
|
|
303
|
+
// Best-effort broadcast — don't fail the notify request
|
|
304
|
+
}
|
|
305
|
+
|
|
162
306
|
if (!title || typeof title !== 'string' || !message || typeof message !== 'string') {
|
|
163
307
|
return json({ error: 'Title and message are required and must be strings' }, { status: 400 });
|
|
164
308
|
}
|
|
@@ -171,22 +315,24 @@ export const POST: RequestHandler = async ({ request }) => {
|
|
|
171
315
|
const requestId = Math.random().toString(36).substring(2, 15);
|
|
172
316
|
const dataRequestId = typeof data?.requestId === 'string' ? data.requestId : undefined;
|
|
173
317
|
const canonicalRequestId = dataRequestId || requestId;
|
|
174
|
-
const shouldSendNotification = intelligentNotificationFilter(
|
|
318
|
+
const shouldSendNotification = intelligentNotificationFilter(
|
|
319
|
+
title,
|
|
320
|
+
message,
|
|
321
|
+
data,
|
|
322
|
+
waitForResponse
|
|
323
|
+
);
|
|
175
324
|
|
|
176
325
|
if (!shouldSendNotification.send) {
|
|
177
|
-
addNotification(
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
title,
|
|
188
|
-
tool: data?.tool ?? null,
|
|
189
|
-
});
|
|
326
|
+
addNotification(
|
|
327
|
+
buildNotificationRecord(
|
|
328
|
+
canonicalRequestId,
|
|
329
|
+
title,
|
|
330
|
+
message,
|
|
331
|
+
'filtered',
|
|
332
|
+
data,
|
|
333
|
+
shouldSendNotification.reason
|
|
334
|
+
)
|
|
335
|
+
);
|
|
190
336
|
|
|
191
337
|
return json({
|
|
192
338
|
message: 'Notification filtered (not sent)',
|
|
@@ -209,19 +355,7 @@ export const POST: RequestHandler = async ({ request }) => {
|
|
|
209
355
|
});
|
|
210
356
|
}
|
|
211
357
|
|
|
212
|
-
addNotification(
|
|
213
|
-
category: data?.category ?? null,
|
|
214
|
-
data: (data as Record<string, unknown>) ?? null,
|
|
215
|
-
error: null,
|
|
216
|
-
id: canonicalRequestId,
|
|
217
|
-
message,
|
|
218
|
-
project: data?.project ?? null,
|
|
219
|
-
source: data?.source ?? null,
|
|
220
|
-
status: 'skipped',
|
|
221
|
-
timestamp: new Date().toISOString(),
|
|
222
|
-
title,
|
|
223
|
-
tool: data?.tool ?? null,
|
|
224
|
-
});
|
|
358
|
+
addNotification(buildNotificationRecord(canonicalRequestId, title, message, 'skipped', data));
|
|
225
359
|
|
|
226
360
|
return json({
|
|
227
361
|
message: 'Push skipped (WebSocket clients connected)',
|
|
@@ -264,15 +398,21 @@ export const POST: RequestHandler = async ({ request }) => {
|
|
|
264
398
|
);
|
|
265
399
|
}
|
|
266
400
|
|
|
267
|
-
// Honor request-scoped deviceToken,
|
|
401
|
+
// Honor request-scoped deviceToken, then the Android-specific env var,
|
|
402
|
+
// then the token auto-registered by the Android app via /api/device-token.
|
|
403
|
+
// env.DEVICE_TOKEN is intentionally NOT in this chain: the iOS branch
|
|
404
|
+
// treats it as an APNs token (see below), and letting it bleed into the
|
|
405
|
+
// FCM path would ship an APNs token to FCM in mixed-platform setups.
|
|
268
406
|
const androidToken =
|
|
269
|
-
requestDeviceToken?.trim() ||
|
|
407
|
+
requestDeviceToken?.trim() ||
|
|
408
|
+
env.ANDROID_DEVICE_TOKEN?.trim() ||
|
|
409
|
+
readPersistedDeviceToken('android');
|
|
270
410
|
|
|
271
411
|
if (!androidToken) {
|
|
272
412
|
return json(
|
|
273
413
|
{
|
|
274
414
|
details:
|
|
275
|
-
'
|
|
415
|
+
'No Android device token available — set ANDROID_DEVICE_TOKEN, pass deviceToken in the request body, or open the Android app so it can auto-register its FCM token.',
|
|
276
416
|
error: 'No device token configured',
|
|
277
417
|
},
|
|
278
418
|
{ status: 500 }
|
|
@@ -293,19 +433,7 @@ export const POST: RequestHandler = async ({ request }) => {
|
|
|
293
433
|
});
|
|
294
434
|
}
|
|
295
435
|
|
|
296
|
-
addNotification(
|
|
297
|
-
category: data?.category ?? null,
|
|
298
|
-
data: (data as Record<string, unknown>) ?? null,
|
|
299
|
-
error: null,
|
|
300
|
-
id: canonicalRequestId,
|
|
301
|
-
message,
|
|
302
|
-
project: data?.project ?? null,
|
|
303
|
-
source: data?.source ?? null,
|
|
304
|
-
status: 'sent',
|
|
305
|
-
timestamp: new Date().toISOString(),
|
|
306
|
-
title,
|
|
307
|
-
tool: data?.tool ?? null,
|
|
308
|
-
});
|
|
436
|
+
addNotification(buildNotificationRecord(canonicalRequestId, title, message, 'sent', data));
|
|
309
437
|
|
|
310
438
|
return json({
|
|
311
439
|
message: 'Notification sent successfully',
|
|
@@ -317,19 +445,16 @@ export const POST: RequestHandler = async ({ request }) => {
|
|
|
317
445
|
} else {
|
|
318
446
|
console.error(`[notify] FCM delivery failed: ${fcmResult.error}`);
|
|
319
447
|
|
|
320
|
-
addNotification(
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
title,
|
|
331
|
-
tool: data?.tool ?? null,
|
|
332
|
-
});
|
|
448
|
+
addNotification(
|
|
449
|
+
buildNotificationRecord(
|
|
450
|
+
canonicalRequestId,
|
|
451
|
+
title,
|
|
452
|
+
message,
|
|
453
|
+
'failed',
|
|
454
|
+
data,
|
|
455
|
+
fcmResult.error
|
|
456
|
+
)
|
|
457
|
+
);
|
|
333
458
|
|
|
334
459
|
return json(
|
|
335
460
|
{
|
|
@@ -384,19 +509,7 @@ export const POST: RequestHandler = async ({ request }) => {
|
|
|
384
509
|
});
|
|
385
510
|
}
|
|
386
511
|
|
|
387
|
-
addNotification(
|
|
388
|
-
category: data?.category ?? null,
|
|
389
|
-
data: (data as Record<string, unknown>) ?? null,
|
|
390
|
-
error: null,
|
|
391
|
-
id: canonicalRequestId,
|
|
392
|
-
message,
|
|
393
|
-
project: data?.project ?? null,
|
|
394
|
-
source: data?.source ?? null,
|
|
395
|
-
status: 'sent',
|
|
396
|
-
timestamp: new Date().toISOString(),
|
|
397
|
-
title,
|
|
398
|
-
tool: data?.tool ?? null,
|
|
399
|
-
});
|
|
512
|
+
addNotification(buildNotificationRecord(canonicalRequestId, title, message, 'sent', data));
|
|
400
513
|
|
|
401
514
|
return json({
|
|
402
515
|
message: 'Notification sent successfully',
|
|
@@ -409,19 +522,9 @@ export const POST: RequestHandler = async ({ request }) => {
|
|
|
409
522
|
const notifErrMsg = toErrorMessage(notificationError);
|
|
410
523
|
console.error(`[notify] APNs delivery failed: ${notifErrMsg}`);
|
|
411
524
|
|
|
412
|
-
addNotification(
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
error: notifErrMsg,
|
|
416
|
-
id: canonicalRequestId,
|
|
417
|
-
message,
|
|
418
|
-
project: data?.project ?? null,
|
|
419
|
-
source: data?.source ?? null,
|
|
420
|
-
status: 'failed',
|
|
421
|
-
timestamp: new Date().toISOString(),
|
|
422
|
-
title,
|
|
423
|
-
tool: data?.tool ?? null,
|
|
424
|
-
});
|
|
525
|
+
addNotification(
|
|
526
|
+
buildNotificationRecord(canonicalRequestId, title, message, 'failed', data, notifErrMsg)
|
|
527
|
+
);
|
|
425
528
|
|
|
426
529
|
return json(
|
|
427
530
|
{
|
|
@@ -65,9 +65,11 @@ export const POST: RequestHandler = async ({ request }) => {
|
|
|
65
65
|
|
|
66
66
|
const existing = ptyManager
|
|
67
67
|
.list()
|
|
68
|
-
.find(
|
|
69
|
-
t
|
|
70
|
-
|
|
68
|
+
.find(
|
|
69
|
+
(t) =>
|
|
70
|
+
t.status === 'running' &&
|
|
71
|
+
(t.sessionFile?.endsWith(`/${sessionId}.jsonl`) || t.openCodeSessionId === sessionId)
|
|
72
|
+
);
|
|
71
73
|
|
|
72
74
|
if (existing) {
|
|
73
75
|
console.log(
|
|
@@ -94,8 +96,7 @@ export const POST: RequestHandler = async ({ request }) => {
|
|
|
94
96
|
|
|
95
97
|
// --- Build args based on command ---
|
|
96
98
|
|
|
97
|
-
const args: string[] =
|
|
98
|
-
command === 'claude' ? ['--resume', sessionId] : ['--session', sessionId];
|
|
99
|
+
const args: string[] = command === 'claude' ? ['--resume', sessionId] : ['--session', sessionId];
|
|
99
100
|
|
|
100
101
|
try {
|
|
101
102
|
const terminal = await ptyManager.create(command, args, realCwd, 120, 40);
|
|
@@ -107,7 +108,10 @@ export const POST: RequestHandler = async ({ request }) => {
|
|
|
107
108
|
return json(
|
|
108
109
|
{
|
|
109
110
|
command: terminal.command,
|
|
110
|
-
createdAt:
|
|
111
|
+
createdAt:
|
|
112
|
+
terminal.createdAt instanceof Date
|
|
113
|
+
? terminal.createdAt.toISOString()
|
|
114
|
+
: terminal.createdAt,
|
|
111
115
|
cwd: terminal.cwd,
|
|
112
116
|
id: terminal.id,
|
|
113
117
|
pid: terminal.pid,
|
|
@@ -9,6 +9,21 @@ import type { RequestHandler } from './$types';
|
|
|
9
9
|
|
|
10
10
|
const ALLOWED_COMMANDS = ['zsh', 'bash', 'sh', 'fish', 'claude', 'opencode'];
|
|
11
11
|
|
|
12
|
+
/** Extract the last non-empty line from a scrollback string. */
|
|
13
|
+
function lastScrollbackLine(scrollback: string): null | string {
|
|
14
|
+
if (!scrollback) {
|
|
15
|
+
return null;
|
|
16
|
+
}
|
|
17
|
+
const lines = scrollback.trimEnd().split('\n');
|
|
18
|
+
for (let i = lines.length - 1; i >= 0; i--) {
|
|
19
|
+
const line = lines[i].trim();
|
|
20
|
+
if (line) {
|
|
21
|
+
return line.slice(0, 200);
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
return null;
|
|
25
|
+
}
|
|
26
|
+
|
|
12
27
|
// GET /api/terminals — List all terminals (active + recently exited)
|
|
13
28
|
export const GET: RequestHandler = ({ request }) => {
|
|
14
29
|
const authError = validateAuth(request);
|
|
@@ -28,6 +43,7 @@ export const GET: RequestHandler = ({ request }) => {
|
|
|
28
43
|
exitedAt: t.exitedAt?.toISOString() ?? null,
|
|
29
44
|
id: t.id,
|
|
30
45
|
isActive: t.isActive,
|
|
46
|
+
lastOutput: lastScrollbackLine(t.scrollback),
|
|
31
47
|
pid: t.pid,
|
|
32
48
|
status: t.status,
|
|
33
49
|
}));
|
|
@@ -127,7 +143,10 @@ export const POST: RequestHandler = async ({ request }) => {
|
|
|
127
143
|
return json(
|
|
128
144
|
{
|
|
129
145
|
command: terminal.command,
|
|
130
|
-
createdAt:
|
|
146
|
+
createdAt:
|
|
147
|
+
terminal.createdAt instanceof Date
|
|
148
|
+
? terminal.createdAt.toISOString()
|
|
149
|
+
: terminal.createdAt,
|
|
131
150
|
cwd: terminal.cwd,
|
|
132
151
|
id: terminal.id,
|
|
133
152
|
pid: terminal.pid,
|
|
@@ -5,6 +5,21 @@ import { json } from '@sveltejs/kit';
|
|
|
5
5
|
|
|
6
6
|
import type { RequestHandler } from './$types';
|
|
7
7
|
|
|
8
|
+
/** Extract the last non-empty line from a scrollback string. */
|
|
9
|
+
function lastScrollbackLine(scrollback: string): null | string {
|
|
10
|
+
if (!scrollback) {
|
|
11
|
+
return null;
|
|
12
|
+
}
|
|
13
|
+
const lines = scrollback.trimEnd().split('\n');
|
|
14
|
+
for (let i = lines.length - 1; i >= 0; i--) {
|
|
15
|
+
const line = lines[i].trim();
|
|
16
|
+
if (line) {
|
|
17
|
+
return line.slice(0, 200);
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
return null;
|
|
21
|
+
}
|
|
22
|
+
|
|
8
23
|
// GET /api/terminals/:id — Get terminal details by ID
|
|
9
24
|
export const GET: RequestHandler = ({ params, request }) => {
|
|
10
25
|
const authError = validateAuth(request);
|
|
@@ -28,8 +43,7 @@ export const GET: RequestHandler = ({ params, request }) => {
|
|
|
28
43
|
exitCode: terminal.exitCode,
|
|
29
44
|
exitedAt: terminal.exitedAt?.toISOString() ?? null,
|
|
30
45
|
id: terminal.id,
|
|
31
|
-
lastOutput:
|
|
32
|
-
terminal.scrollback.length > 0 ? terminal.scrollback[terminal.scrollback.length - 1] : null,
|
|
46
|
+
lastOutput: lastScrollbackLine(terminal.scrollback),
|
|
33
47
|
pid: terminal.pid,
|
|
34
48
|
sessionWs: `/ws/session/${terminal.id}`,
|
|
35
49
|
status: terminal.status,
|
|
@@ -1,40 +1,12 @@
|
|
|
1
1
|
import { validateAuth } from '$lib/modules/server/auth';
|
|
2
|
-
import { toErrorMessage } from '$lib/modules/server/utils/error';
|
|
3
2
|
import { json } from '@sveltejs/kit';
|
|
4
3
|
|
|
5
4
|
import type { RequestHandler } from './$types';
|
|
6
5
|
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
const authError = validateAuth(request);
|
|
12
|
-
if (authError) {
|
|
13
|
-
return authError;
|
|
14
|
-
}
|
|
15
|
-
|
|
16
|
-
const body = (await request.json()) as Record<string, unknown>;
|
|
17
|
-
|
|
18
|
-
console.log('Webhook received:', {
|
|
19
|
-
body,
|
|
20
|
-
timestamp: new Date().toISOString(),
|
|
21
|
-
});
|
|
22
|
-
|
|
23
|
-
// In a full implementation, this would forward to Claude Code
|
|
24
|
-
// For now, just log and acknowledge
|
|
25
|
-
|
|
26
|
-
return json({
|
|
27
|
-
message: 'Webhook received successfully',
|
|
28
|
-
success: true,
|
|
29
|
-
timestamp: new Date().toISOString(),
|
|
30
|
-
});
|
|
31
|
-
} catch (error) {
|
|
32
|
-
console.error('[webhook] Failed to process webhook:', toErrorMessage(error));
|
|
33
|
-
return json(
|
|
34
|
-
{
|
|
35
|
-
error: 'Failed to process webhook',
|
|
36
|
-
},
|
|
37
|
-
{ status: 500 }
|
|
38
|
-
);
|
|
6
|
+
export const POST: RequestHandler = ({ request }) => {
|
|
7
|
+
const authError = validateAuth(request);
|
|
8
|
+
if (authError) {
|
|
9
|
+
return authError;
|
|
39
10
|
}
|
|
11
|
+
return json({ error: 'Webhook endpoint not implemented' }, { status: 501 });
|
|
40
12
|
};
|