@juspay/shooter 1.0.0 → 1.2.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 +117 -33
- package/.claude/settings.json +14 -14
- package/README.md +116 -84
- package/bin/shooter.cjs +471 -102
- package/build/client/_app/immutable/assets/{0.CM9Hl6d-.css → 0.BhZOCxO4.css} +1 -1
- package/build/client/_app/immutable/assets/0.BhZOCxO4.css.br +0 -0
- package/build/client/_app/immutable/assets/0.BhZOCxO4.css.gz +0 -0
- package/build/client/_app/immutable/assets/1.BYutk3aU.css +1 -0
- package/build/client/_app/immutable/assets/1.BYutk3aU.css.br +0 -0
- package/build/client/_app/immutable/assets/1.BYutk3aU.css.gz +0 -0
- package/build/client/_app/immutable/assets/2.CAShZ7lQ.css.gz +0 -0
- package/build/client/_app/immutable/assets/3.DGDHCVnW.css +1 -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/assets/4.BFUut--w.css +1 -0
- package/build/client/_app/immutable/assets/4.BFUut--w.css.br +0 -0
- package/build/client/_app/immutable/assets/4.BFUut--w.css.gz +0 -0
- package/build/client/_app/immutable/assets/5.BTOx7yt7.css +1 -0
- package/build/client/_app/immutable/assets/5.BTOx7yt7.css.br +0 -0
- package/build/client/_app/immutable/assets/5.BTOx7yt7.css.gz +0 -0
- package/build/client/_app/immutable/assets/6.eZGZN-BF.css +1 -0
- package/build/client/_app/immutable/assets/6.eZGZN-BF.css.br +0 -0
- package/build/client/_app/immutable/assets/6.eZGZN-BF.css.gz +0 -0
- package/build/client/_app/immutable/assets/7.DwS5ZHBh.css +1 -0
- package/build/client/_app/immutable/assets/7.DwS5ZHBh.css.br +0 -0
- package/build/client/_app/immutable/assets/7.DwS5ZHBh.css.gz +0 -0
- package/build/client/_app/immutable/assets/ChatView.CwWbzIL-.css +1 -0
- package/build/client/_app/immutable/assets/ChatView.CwWbzIL-.css.br +0 -0
- package/build/client/_app/immutable/assets/ChatView.CwWbzIL-.css.gz +0 -0
- package/build/client/_app/immutable/assets/Phone.FQEfwCX2.css +1 -0
- package/build/client/_app/immutable/assets/Phone.FQEfwCX2.css.br +0 -0
- package/build/client/_app/immutable/assets/Phone.FQEfwCX2.css.gz +0 -0
- package/build/client/_app/immutable/assets/markdown.Dc-OSJWY.css +1 -0
- package/build/client/_app/immutable/assets/markdown.Dc-OSJWY.css.br +0 -0
- package/build/client/_app/immutable/assets/markdown.Dc-OSJWY.css.gz +0 -0
- package/build/client/_app/immutable/assets/xterm.DFuMZ0ql.css.gz +0 -0
- package/build/client/_app/immutable/chunks/B-K5Sh65.js +1 -0
- package/build/client/_app/immutable/chunks/B-K5Sh65.js.br +0 -0
- package/build/client/_app/immutable/chunks/B-K5Sh65.js.gz +0 -0
- package/build/client/_app/immutable/chunks/B5NAKyil.js +20 -0
- 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 +1 -0
- 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 +6 -0
- 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/BLszSzTT.js +1 -0
- package/build/client/_app/immutable/chunks/BLszSzTT.js.br +0 -0
- package/build/client/_app/immutable/chunks/BLszSzTT.js.gz +0 -0
- package/build/client/_app/immutable/chunks/BOYo8yTr.js +1 -0
- 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/BTGVxaYV.js.gz +0 -0
- package/build/client/_app/immutable/chunks/BYqGCrTe.js +1 -0
- package/build/client/_app/immutable/chunks/BYqGCrTe.js.br +0 -0
- package/build/client/_app/immutable/chunks/BYqGCrTe.js.gz +0 -0
- package/build/client/_app/immutable/chunks/BlxrFPDK.js.gz +0 -0
- package/build/client/_app/immutable/chunks/Bu1aqm5j.js +1 -0
- 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/C4mLaWWx.js +1 -0
- package/build/client/_app/immutable/chunks/C4mLaWWx.js.br +0 -0
- package/build/client/_app/immutable/chunks/C4mLaWWx.js.gz +0 -0
- package/build/client/_app/immutable/chunks/CQjSATpv.js +61 -0
- 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 +1 -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 +1 -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/DLu6yJIZ.js.gz +0 -0
- package/build/client/_app/immutable/chunks/DSU1n5N_.js +1 -0
- 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 +1 -0
- 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 +41 -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/PPVm8Dsz.js.gz +0 -0
- package/build/client/_app/immutable/chunks/UJOiqIYE.js +1 -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 +2 -0
- 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.Z3zMnuSx.js +2 -0
- package/build/client/_app/immutable/entry/app.Z3zMnuSx.js.br +0 -0
- package/build/client/_app/immutable/entry/app.Z3zMnuSx.js.gz +0 -0
- package/build/client/_app/immutable/entry/start.Dd-gIP4y.js +1 -0
- package/build/client/_app/immutable/entry/start.Dd-gIP4y.js.br +2 -0
- package/build/client/_app/immutable/entry/start.Dd-gIP4y.js.gz +0 -0
- package/build/client/_app/immutable/nodes/0.D2YR8tTD.js +1 -0
- package/build/client/_app/immutable/nodes/0.D2YR8tTD.js.br +0 -0
- package/build/client/_app/immutable/nodes/0.D2YR8tTD.js.gz +0 -0
- package/build/client/_app/immutable/nodes/1.B3m6rO4C.js +1 -0
- package/build/client/_app/immutable/nodes/1.B3m6rO4C.js.br +0 -0
- package/build/client/_app/immutable/nodes/1.B3m6rO4C.js.gz +0 -0
- package/build/client/_app/immutable/nodes/2.CyRB2euU.js +1 -0
- package/build/client/_app/immutable/nodes/2.CyRB2euU.js.br +0 -0
- package/build/client/_app/immutable/nodes/2.CyRB2euU.js.gz +0 -0
- package/build/client/_app/immutable/nodes/3.3yohCM25.js +3 -0
- 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.DEAcwl7l.js +1 -0
- package/build/client/_app/immutable/nodes/4.DEAcwl7l.js.br +0 -0
- package/build/client/_app/immutable/nodes/4.DEAcwl7l.js.gz +0 -0
- package/build/client/_app/immutable/nodes/5.C6bLGWQR.js +4 -0
- package/build/client/_app/immutable/nodes/5.C6bLGWQR.js.br +0 -0
- package/build/client/_app/immutable/nodes/5.C6bLGWQR.js.gz +0 -0
- package/build/client/_app/immutable/nodes/6.ByTzlA2D.js +2 -0
- package/build/client/_app/immutable/nodes/6.ByTzlA2D.js.br +0 -0
- package/build/client/_app/immutable/nodes/6.ByTzlA2D.js.gz +0 -0
- package/build/client/_app/immutable/nodes/7.BPMfwzd2.js +2 -0
- package/build/client/_app/immutable/nodes/7.BPMfwzd2.js.br +0 -0
- package/build/client/_app/immutable/nodes/7.BPMfwzd2.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/client/favicon.svg.gz +0 -0
- package/build/client/manifest.json +13 -0
- package/build/client/manifest.json.br +0 -0
- package/build/client/manifest.json.gz +0 -0
- package/build/pty-holder.cjs +37 -8
- package/build/server/chunks/0-Vk38tI2J.js +9 -0
- package/build/server/chunks/0-Vk38tI2J.js.map +1 -0
- package/build/server/chunks/1-BvYQX5MR.js +9 -0
- package/build/server/chunks/1-BvYQX5MR.js.map +1 -0
- package/build/server/chunks/2-Cl7R4Qk2.js +9 -0
- package/build/server/chunks/2-Cl7R4Qk2.js.map +1 -0
- package/build/server/chunks/3-Ck7ewhOX.js +9 -0
- package/build/server/chunks/3-Ck7ewhOX.js.map +1 -0
- package/build/server/chunks/4-CnDeRm2Z.js +9 -0
- package/build/server/chunks/4-CnDeRm2Z.js.map +1 -0
- package/build/server/chunks/5-IxitzEvN.js +9 -0
- package/build/server/chunks/5-IxitzEvN.js.map +1 -0
- package/build/server/chunks/6-CyZ3r1iS.js +9 -0
- package/build/server/chunks/6-CyZ3r1iS.js.map +1 -0
- package/build/server/chunks/7-BmI7du46.js +9 -0
- package/build/server/chunks/7-BmI7du46.js.map +1 -0
- package/build/server/chunks/Button-Cs1aE6ka.js +80 -0
- package/build/server/chunks/Button-Cs1aE6ka.js.map +1 -0
- package/build/server/chunks/EmptyState-DDFH1K8g.js +26 -0
- package/build/server/chunks/EmptyState-DDFH1K8g.js.map +1 -0
- package/build/server/chunks/Icon-CEUrotA6.js +36 -0
- package/build/server/chunks/Icon-CEUrotA6.js.map +1 -0
- package/build/server/chunks/Shimmer-DB8W1zt6.js +10 -0
- package/build/server/chunks/Shimmer-DB8W1zt6.js.map +1 -0
- package/build/server/chunks/_error.svelte-uCOJNxvr.js +39 -0
- package/build/server/chunks/_error.svelte-uCOJNxvr.js.map +1 -0
- package/build/server/chunks/_layout.svelte-CtWmEJwe.js +56 -0
- package/build/server/chunks/_layout.svelte-CtWmEJwe.js.map +1 -0
- package/build/server/chunks/_page.svelte-BcZaKdX9.js +45 -0
- package/build/server/chunks/_page.svelte-BcZaKdX9.js.map +1 -0
- package/build/server/chunks/_page.svelte-BdYynOck.js +85 -0
- package/build/server/chunks/_page.svelte-BdYynOck.js.map +1 -0
- package/build/server/chunks/_page.svelte-BgevQjq1.js +101 -0
- package/build/server/chunks/_page.svelte-BgevQjq1.js.map +1 -0
- package/build/server/chunks/_page.svelte-CVq6tRb3.js +550 -0
- package/build/server/chunks/_page.svelte-CVq6tRb3.js.map +1 -0
- package/build/server/chunks/_page.svelte-CxWcQ0Am.js +651 -0
- package/build/server/chunks/_page.svelte-CxWcQ0Am.js.map +1 -0
- package/build/server/chunks/_page.svelte-DO4oa_LY.js +44 -0
- package/build/server/chunks/_page.svelte-DO4oa_LY.js.map +1 -0
- package/build/server/chunks/{_server.ts-CbDRDIoP.js → _server.ts-BStnNIcq.js} +9 -11
- package/build/server/chunks/_server.ts-BStnNIcq.js.map +1 -0
- package/build/server/chunks/{_server.ts-DRVbgm6k.js → _server.ts-CAxsWKvS.js} +22 -25
- package/build/server/chunks/_server.ts-CAxsWKvS.js.map +1 -0
- package/build/server/chunks/{_server.ts-CPa6DgIt.js → _server.ts-COu0vNpd.js} +6 -6
- package/build/server/chunks/_server.ts-COu0vNpd.js.map +1 -0
- package/build/server/chunks/{_server.ts-C29xzfaw.js → _server.ts-CTpcLUH8.js} +10 -10
- package/build/server/chunks/_server.ts-CTpcLUH8.js.map +1 -0
- package/build/server/chunks/{_server.ts-D4MNi4cD.js → _server.ts-Cf84YIaW.js} +3 -3
- package/build/server/chunks/{_server.ts-D4MNi4cD.js.map → _server.ts-Cf84YIaW.js.map} +1 -1
- package/build/server/chunks/{_server.ts-BL2FGb5Z.js → _server.ts-Ch-6iOHp.js} +99 -53
- package/build/server/chunks/_server.ts-Ch-6iOHp.js.map +1 -0
- package/build/server/chunks/_server.ts-CtH0dhUp.js +71 -0
- package/build/server/chunks/_server.ts-CtH0dhUp.js.map +1 -0
- package/build/server/chunks/_server.ts-DB_Kg97c.js +73 -0
- package/build/server/chunks/_server.ts-DB_Kg97c.js.map +1 -0
- package/build/server/chunks/{_server.ts-DfajWaqh.js → _server.ts-DV8zTCF9.js} +7 -9
- package/build/server/chunks/_server.ts-DV8zTCF9.js.map +1 -0
- package/build/server/chunks/_server.ts-DYpJImqd.js +99 -0
- package/build/server/chunks/_server.ts-DYpJImqd.js.map +1 -0
- package/build/server/chunks/{_server.ts-ColfDHW8.js → _server.ts-DYvb9ijZ.js} +21 -10
- package/build/server/chunks/_server.ts-DYvb9ijZ.js.map +1 -0
- package/build/server/chunks/{_server.ts-Cv_OrRuL.js → _server.ts-Deok2y88.js} +209 -34
- package/build/server/chunks/_server.ts-Deok2y88.js.map +1 -0
- package/build/server/chunks/{_server.ts-y9-WYDMa.js → _server.ts-WhTJBEJy.js} +5 -4
- package/build/server/chunks/{_server.ts-y9-WYDMa.js.map → _server.ts-WhTJBEJy.js.map} +1 -1
- package/build/server/chunks/{_server.ts-BjOJsoy4.js → _server.ts-XzT2UHM1.js} +6 -5
- package/build/server/chunks/_server.ts-XzT2UHM1.js.map +1 -0
- package/build/server/chunks/{_server.ts-BgdjBZco.js → _server.ts-tSpgyl1D.js} +7 -5
- package/build/server/chunks/_server.ts-tSpgyl1D.js.map +1 -0
- package/build/server/chunks/{_server.ts-BihKSdj_.js → _server.ts-vekTmWAx.js} +8 -8
- package/build/server/chunks/_server.ts-vekTmWAx.js.map +1 -0
- package/build/server/chunks/{auth-CEgFis71.js → auth-DeCdZ83n.js} +2 -2
- package/build/server/chunks/{auth-CEgFis71.js.map → auth-DeCdZ83n.js.map} +1 -1
- package/build/server/chunks/client-BdGHe_hY.js +25 -0
- package/build/server/chunks/client-BdGHe_hY.js.map +1 -0
- package/build/server/chunks/client2-CCBGA-2V.js +7 -0
- package/build/server/chunks/client2-CCBGA-2V.js.map +1 -0
- package/build/server/chunks/error-DDXB3duW.js +12 -0
- package/build/server/chunks/error-DDXB3duW.js.map +1 -0
- package/build/server/chunks/{exports-CJ0Q5XmL.js → index-DwaY1cAm.js} +1111 -1634
- package/build/server/chunks/index-DwaY1cAm.js.map +1 -0
- package/build/server/chunks/index-server-CrDaL06Y.js +9 -0
- package/build/server/chunks/index-server-CrDaL06Y.js.map +1 -0
- package/build/server/chunks/index2-CgclKpUj.js +58 -0
- package/build/server/chunks/index2-CgclKpUj.js.map +1 -0
- package/build/server/chunks/{library-apns-BHxLmuIx.js → library-apns-BqJbvSKh.js} +4 -4
- package/build/server/chunks/library-apns-BqJbvSKh.js.map +1 -0
- package/build/server/chunks/markdown-W_mTBct0.js +8 -0
- package/build/server/chunks/markdown-W_mTBct0.js.map +1 -0
- package/build/server/chunks/opencode-db-path-DcfhJtJy.js +15 -0
- package/build/server/chunks/opencode-db-path-DcfhJtJy.js.map +1 -0
- package/build/server/chunks/{pty-manager-C0FhBiVq.js → pty-manager-BQVB7IVj.js} +155 -326
- package/build/server/chunks/pty-manager-BQVB7IVj.js.map +1 -0
- package/build/server/chunks/root-DDSnEAZv.js +1171 -0
- package/build/server/chunks/root-DDSnEAZv.js.map +1 -0
- package/build/server/chunks/{shared-server-BDY8jh20.js → shared-server-sSGG17Df.js} +2 -3
- package/build/server/chunks/{shared-server-BDY8jh20.js.map → shared-server-sSGG17Df.js.map} +1 -1
- package/build/server/chunks/state.svelte-hBbXlUak.js +11 -0
- package/build/server/chunks/state.svelte-hBbXlUak.js.map +1 -0
- package/build/server/chunks/stores-DHNzYNpX.js +28 -0
- package/build/server/chunks/stores-DHNzYNpX.js.map +1 -0
- package/build/server/index.js +1085 -2242
- package/build/server/index.js.map +1 -1
- package/build/server/manifest.js +39 -25
- package/build/server/manifest.js.map +1 -1
- package/package.json +32 -9
- package/scripts/fix-generated-types.sh +37 -0
- package/scripts/homebrew/shooter.rb +51 -0
- package/scripts/install.sh +348 -186
- package/scripts/setup.cjs +215 -45
- package/server.ts +114 -71
- package/src/app.css +12 -3
- package/src/app.d.ts +13 -20
- package/src/app.html +3 -2
- package/src/generated/types/API.ts +280 -0
- package/src/generated/types/APN.ts +186 -203
- package/src/generated/types/CLI.ts +18 -25
- package/src/generated/types/Client.ts +589 -0
- package/src/generated/types/Config.ts +53 -0
- package/src/generated/types/Holder.ts +638 -0
- package/src/generated/types/JWT.ts +39 -50
- package/src/generated/types/Notification.ts +426 -0
- package/src/generated/types/OpenCode.ts +356 -0
- package/src/generated/types/Sessions.ts +570 -0
- package/src/generated/types/Terminal.ts +2184 -2071
- package/src/generated/types/WsProtocol.ts +2004 -0
- package/src/generated/types/index.ts +9 -3
- package/src/lib/env.ts +29 -0
- package/src/lib/modules/client/common/cache.ts +10 -2
- package/src/lib/modules/client/common/config-guard.ts +37 -5
- package/src/lib/modules/client/common/error.ts +10 -0
- package/src/lib/modules/client/common/index.ts +6 -5
- package/src/lib/modules/client/common/markdown.ts +22 -1
- package/src/lib/modules/client/common/native-bridge.ts +28 -20
- package/src/lib/modules/client/common/time.ts +13 -11
- package/src/lib/modules/client/terminal/ChatView.svelte +354 -74
- package/src/lib/modules/client/terminal/CommandPalette.svelte +3 -2
- package/src/lib/modules/client/terminal/ConnectionStatus.svelte +7 -1
- package/src/lib/modules/client/terminal/LaunchSheet.svelte +147 -84
- package/src/lib/modules/client/terminal/QuickKeys.svelte +3 -1
- package/src/lib/modules/client/terminal/ShortcutsHelp.svelte +2 -5
- package/src/lib/modules/client/terminal/keyboard-shortcuts.ts +27 -24
- package/src/lib/modules/client/terminal/xterm-wrapper.ts +74 -45
- package/src/lib/modules/server/apn/library-apns.ts +3 -2
- package/src/lib/modules/server/apn/notification-history.ts +2 -13
- package/src/lib/modules/server/apn/notification-sessions.ts +3 -13
- package/src/lib/modules/server/apn/pending-requests.ts +3 -8
- package/src/lib/modules/server/apn/types.ts +5 -4
- package/src/lib/modules/server/cli/index.ts +3 -2
- package/src/lib/modules/server/fcm/fcm-service.ts +8 -6
- package/src/lib/modules/server/sessions/jsonl-parser.ts +3 -3
- package/src/lib/modules/server/sessions/jsonl-reader.ts +86 -26
- package/src/lib/modules/server/sessions/opencode-db-path.ts +26 -0
- package/src/lib/modules/server/sessions/opencode-reader.ts +13 -15
- package/src/lib/modules/server/sessions/process-detector.ts +103 -0
- package/src/lib/modules/server/sessions/types.ts +11 -22
- package/src/lib/modules/server/terminal/holder-client.ts +272 -248
- package/src/lib/modules/server/terminal/opencode-watcher.ts +547 -556
- package/src/lib/modules/server/terminal/pty-holder.cjs +37 -8
- package/src/lib/modules/server/terminal/pty-manager.ts +157 -115
- package/src/lib/modules/server/terminal/session-watcher.ts +6 -4
- package/src/lib/modules/server/terminal/terminal-store.ts +131 -128
- package/src/lib/modules/server/utils/error.ts +9 -0
- package/src/lib/modules/server/ws/events-handler.ts +12 -6
- package/src/lib/modules/server/ws/keepalive.ts +86 -69
- package/src/lib/modules/server/ws/server.ts +43 -37
- package/src/lib/modules/server/ws/session-handler.ts +332 -147
- package/src/lib/modules/server/ws/terminal-handler.ts +29 -17
- package/src/lib/modules/server/ws/ticket-store.ts +29 -26
- package/src/lib/theme.css +30 -0
- package/src/lib/types/config.ts +1 -6
- package/src/routes/+error.svelte +94 -0
- package/src/routes/+layout.svelte +66 -31
- package/src/routes/+page.svelte +25 -22
- package/src/routes/api/debug/+server.ts +3 -1
- package/src/routes/api/device-token/+server.ts +60 -60
- package/src/routes/api/health/+server.ts +81 -73
- package/src/routes/api/notify/+server.ts +115 -68
- package/src/routes/api/qr-config/+server.ts +30 -32
- package/src/routes/api/response/+server.ts +9 -4
- package/src/routes/api/sessions/+server.ts +15 -5
- package/src/routes/api/sessions/connect/+server.ts +125 -0
- package/src/routes/api/sessions/detect/+server.ts +27 -0
- package/src/routes/api/terminals/+server.ts +26 -24
- package/src/routes/api/terminals/[id]/+server.ts +13 -7
- package/src/routes/api/terminals/[id]/paste-image/+server.ts +54 -52
- package/src/routes/api/terminals/[id]/resize/+server.ts +6 -3
- package/src/routes/api/webhook/+server.ts +8 -10
- package/src/routes/api/ws-status/+server.ts +7 -5
- package/src/routes/api/ws-ticket/+server.ts +42 -41
- package/src/routes/config/+page.svelte +149 -75
- package/src/routes/project/+page.svelte +165 -35
- package/src/routes/session/[id]/+page.svelte +479 -283
- package/src/routes/terminals/+page.svelte +58 -45
- package/src/routes/terminals/[id]/+page.svelte +223 -91
- package/build/client/_app/immutable/assets/0.CM9Hl6d-.css.br +0 -0
- package/build/client/_app/immutable/assets/0.CM9Hl6d-.css.gz +0 -0
- package/build/client/_app/immutable/assets/3.C0uFg0IS.css +0 -1
- package/build/client/_app/immutable/assets/3.C0uFg0IS.css.br +0 -0
- package/build/client/_app/immutable/assets/3.C0uFg0IS.css.gz +0 -0
- package/build/client/_app/immutable/assets/4.cJuCkJKZ.css +0 -1
- package/build/client/_app/immutable/assets/4.cJuCkJKZ.css.br +0 -0
- package/build/client/_app/immutable/assets/4.cJuCkJKZ.css.gz +0 -0
- package/build/client/_app/immutable/assets/5.DRjApZQW.css +0 -1
- package/build/client/_app/immutable/assets/5.DRjApZQW.css.br +0 -0
- package/build/client/_app/immutable/assets/5.DRjApZQW.css.gz +0 -0
- package/build/client/_app/immutable/assets/6.AraZrY8I.css +0 -1
- package/build/client/_app/immutable/assets/6.AraZrY8I.css.br +0 -0
- package/build/client/_app/immutable/assets/6.AraZrY8I.css.gz +0 -0
- package/build/client/_app/immutable/assets/7.BCJ1IuMx.css +0 -1
- package/build/client/_app/immutable/assets/7.BCJ1IuMx.css.br +0 -0
- package/build/client/_app/immutable/assets/7.BCJ1IuMx.css.gz +0 -0
- package/build/client/_app/immutable/assets/ChatView.CsdBAOKx.css +0 -1
- package/build/client/_app/immutable/assets/ChatView.CsdBAOKx.css.br +0 -0
- package/build/client/_app/immutable/assets/ChatView.CsdBAOKx.css.gz +0 -0
- package/build/client/_app/immutable/assets/markdown.B0b5w2tq.css +0 -1
- package/build/client/_app/immutable/assets/markdown.B0b5w2tq.css.br +0 -0
- package/build/client/_app/immutable/assets/markdown.B0b5w2tq.css.gz +0 -0
- package/build/client/_app/immutable/chunks/BNJphC1q.js +0 -56
- package/build/client/_app/immutable/chunks/BNJphC1q.js.br +0 -0
- package/build/client/_app/immutable/chunks/BNJphC1q.js.gz +0 -0
- package/build/client/_app/immutable/chunks/Bvk7mfPM.js +0 -1
- package/build/client/_app/immutable/chunks/Bvk7mfPM.js.br +0 -0
- package/build/client/_app/immutable/chunks/Bvk7mfPM.js.gz +0 -0
- package/build/client/_app/immutable/chunks/CAokzuPQ.js +0 -1
- package/build/client/_app/immutable/chunks/CAokzuPQ.js.br +0 -0
- package/build/client/_app/immutable/chunks/CAokzuPQ.js.gz +0 -0
- package/build/client/_app/immutable/chunks/CGLrx-H5.js +0 -1
- package/build/client/_app/immutable/chunks/CGLrx-H5.js.br +0 -0
- package/build/client/_app/immutable/chunks/CGLrx-H5.js.gz +0 -0
- package/build/client/_app/immutable/chunks/CgCpWzEA.js +0 -1
- package/build/client/_app/immutable/chunks/CgCpWzEA.js.br +0 -0
- package/build/client/_app/immutable/chunks/CgCpWzEA.js.gz +0 -0
- package/build/client/_app/immutable/chunks/Cjwk_cGO.js +0 -6
- package/build/client/_app/immutable/chunks/Cjwk_cGO.js.br +0 -0
- package/build/client/_app/immutable/chunks/Cjwk_cGO.js.gz +0 -0
- package/build/client/_app/immutable/chunks/CtQ8EED1.js +0 -11
- package/build/client/_app/immutable/chunks/CtQ8EED1.js.br +0 -0
- package/build/client/_app/immutable/chunks/CtQ8EED1.js.gz +0 -0
- package/build/client/_app/immutable/chunks/DERQCisl.js +0 -1
- package/build/client/_app/immutable/chunks/DERQCisl.js.br +0 -0
- package/build/client/_app/immutable/chunks/DERQCisl.js.gz +0 -0
- package/build/client/_app/immutable/chunks/DKrg8TQs.js +0 -1
- package/build/client/_app/immutable/chunks/DKrg8TQs.js.br +0 -0
- package/build/client/_app/immutable/chunks/DKrg8TQs.js.gz +0 -0
- package/build/client/_app/immutable/chunks/Dkkpz_4D.js +0 -126
- package/build/client/_app/immutable/chunks/Dkkpz_4D.js.br +0 -0
- package/build/client/_app/immutable/chunks/Dkkpz_4D.js.gz +0 -0
- package/build/client/_app/immutable/chunks/DoczjQhA.js +0 -1
- package/build/client/_app/immutable/chunks/DoczjQhA.js.br +0 -0
- package/build/client/_app/immutable/chunks/DoczjQhA.js.gz +0 -0
- package/build/client/_app/immutable/chunks/RpcNruLP.js +0 -2
- package/build/client/_app/immutable/chunks/RpcNruLP.js.br +0 -0
- package/build/client/_app/immutable/chunks/RpcNruLP.js.gz +0 -0
- package/build/client/_app/immutable/chunks/a-St0Zwo.js +0 -1
- package/build/client/_app/immutable/chunks/a-St0Zwo.js.br +0 -0
- package/build/client/_app/immutable/chunks/a-St0Zwo.js.gz +0 -0
- package/build/client/_app/immutable/chunks/bo70OQUZ.js +0 -1
- package/build/client/_app/immutable/chunks/bo70OQUZ.js.br +0 -0
- package/build/client/_app/immutable/chunks/bo70OQUZ.js.gz +0 -0
- package/build/client/_app/immutable/entry/app.QvGgdvTI.js +0 -2
- package/build/client/_app/immutable/entry/app.QvGgdvTI.js.br +0 -0
- package/build/client/_app/immutable/entry/app.QvGgdvTI.js.gz +0 -0
- package/build/client/_app/immutable/entry/start.BntDNRMC.js +0 -1
- package/build/client/_app/immutable/entry/start.BntDNRMC.js.br +0 -0
- package/build/client/_app/immutable/entry/start.BntDNRMC.js.gz +0 -0
- package/build/client/_app/immutable/nodes/0.CzkdvJ7j.js +0 -1
- package/build/client/_app/immutable/nodes/0.CzkdvJ7j.js.br +0 -0
- package/build/client/_app/immutable/nodes/0.CzkdvJ7j.js.gz +0 -0
- package/build/client/_app/immutable/nodes/1.MG1QhfrI.js +0 -1
- package/build/client/_app/immutable/nodes/1.MG1QhfrI.js.br +0 -0
- package/build/client/_app/immutable/nodes/1.MG1QhfrI.js.gz +0 -0
- package/build/client/_app/immutable/nodes/2.B4MlOSh6.js +0 -1
- package/build/client/_app/immutable/nodes/2.B4MlOSh6.js.br +0 -0
- package/build/client/_app/immutable/nodes/2.B4MlOSh6.js.gz +0 -0
- package/build/client/_app/immutable/nodes/3.DIwYkjDn.js +0 -3
- package/build/client/_app/immutable/nodes/3.DIwYkjDn.js.br +0 -0
- package/build/client/_app/immutable/nodes/3.DIwYkjDn.js.gz +0 -0
- package/build/client/_app/immutable/nodes/4.D-cIe70D.js +0 -1
- package/build/client/_app/immutable/nodes/4.D-cIe70D.js.br +0 -0
- package/build/client/_app/immutable/nodes/4.D-cIe70D.js.gz +0 -0
- package/build/client/_app/immutable/nodes/5.D7zPRe3L.js +0 -1
- package/build/client/_app/immutable/nodes/5.D7zPRe3L.js.br +0 -0
- package/build/client/_app/immutable/nodes/5.D7zPRe3L.js.gz +0 -0
- package/build/client/_app/immutable/nodes/6.BB7QE48r.js +0 -2
- package/build/client/_app/immutable/nodes/6.BB7QE48r.js.br +0 -0
- package/build/client/_app/immutable/nodes/6.BB7QE48r.js.gz +0 -0
- package/build/client/_app/immutable/nodes/7.D8mqsrZG.js +0 -2
- package/build/client/_app/immutable/nodes/7.D8mqsrZG.js.br +0 -0
- package/build/client/_app/immutable/nodes/7.D8mqsrZG.js.gz +0 -0
- package/build/client/manifest.webmanifest +0 -1
- package/build/client/registerSW.js +0 -1
- package/build/client/registerSW.js.br +0 -0
- package/build/client/registerSW.js.gz +0 -0
- package/build/client/sw.js +0 -222
- package/build/client/sw.js.br +0 -0
- package/build/client/sw.js.gz +0 -0
- package/build/client/workbox-5119daf5.js +0 -3395
- package/build/client/workbox-5119daf5.js.br +0 -0
- package/build/client/workbox-5119daf5.js.gz +0 -0
- package/build/server/chunks/0-q2IUp76Y.js +0 -9
- package/build/server/chunks/0-q2IUp76Y.js.map +0 -1
- package/build/server/chunks/1-CU50G5wZ.js +0 -9
- package/build/server/chunks/1-CU50G5wZ.js.map +0 -1
- package/build/server/chunks/2-D01t9s8T.js +0 -9
- package/build/server/chunks/2-D01t9s8T.js.map +0 -1
- package/build/server/chunks/3-5PUQ04wC.js +0 -9
- package/build/server/chunks/3-5PUQ04wC.js.map +0 -1
- package/build/server/chunks/4-e7gywnSG.js +0 -9
- package/build/server/chunks/4-e7gywnSG.js.map +0 -1
- package/build/server/chunks/5-CA1SA6KZ.js +0 -9
- package/build/server/chunks/5-CA1SA6KZ.js.map +0 -1
- package/build/server/chunks/6-71H221sV.js +0 -9
- package/build/server/chunks/6-71H221sV.js.map +0 -1
- package/build/server/chunks/7-Bo-vmdyz.js +0 -9
- package/build/server/chunks/7-Bo-vmdyz.js.map +0 -1
- package/build/server/chunks/_layout.svelte-SFHOxs74.js +0 -132
- package/build/server/chunks/_layout.svelte-SFHOxs74.js.map +0 -1
- package/build/server/chunks/_page.svelte-B4w-2wD-.js +0 -120
- package/build/server/chunks/_page.svelte-B4w-2wD-.js.map +0 -1
- package/build/server/chunks/_page.svelte-B_qAXjkh.js +0 -213
- package/build/server/chunks/_page.svelte-B_qAXjkh.js.map +0 -1
- package/build/server/chunks/_page.svelte-CsF1_TRG.js +0 -50
- package/build/server/chunks/_page.svelte-CsF1_TRG.js.map +0 -1
- package/build/server/chunks/_page.svelte-DJC6U-P0.js +0 -68
- package/build/server/chunks/_page.svelte-DJC6U-P0.js.map +0 -1
- package/build/server/chunks/_page.svelte-DQ6HBtsz.js +0 -407
- package/build/server/chunks/_page.svelte-DQ6HBtsz.js.map +0 -1
- package/build/server/chunks/_page.svelte-LbhhjP21.js +0 -148
- package/build/server/chunks/_page.svelte-LbhhjP21.js.map +0 -1
- package/build/server/chunks/_server.ts-BL2FGb5Z.js.map +0 -1
- package/build/server/chunks/_server.ts-BgdjBZco.js.map +0 -1
- package/build/server/chunks/_server.ts-BihKSdj_.js.map +0 -1
- package/build/server/chunks/_server.ts-BjOJsoy4.js.map +0 -1
- package/build/server/chunks/_server.ts-C29xzfaw.js.map +0 -1
- package/build/server/chunks/_server.ts-CPa6DgIt.js.map +0 -1
- package/build/server/chunks/_server.ts-CbDRDIoP.js.map +0 -1
- package/build/server/chunks/_server.ts-Cl1OEWL4.js +0 -54
- package/build/server/chunks/_server.ts-Cl1OEWL4.js.map +0 -1
- package/build/server/chunks/_server.ts-ColfDHW8.js.map +0 -1
- package/build/server/chunks/_server.ts-Cv_OrRuL.js.map +0 -1
- package/build/server/chunks/_server.ts-DRVbgm6k.js.map +0 -1
- package/build/server/chunks/_server.ts-DfajWaqh.js.map +0 -1
- package/build/server/chunks/client-CxCatAKr.js +0 -255
- package/build/server/chunks/client-CxCatAKr.js.map +0 -1
- package/build/server/chunks/error.svelte-BqdwMWdK.js +0 -26
- package/build/server/chunks/error.svelte-BqdwMWdK.js.map +0 -1
- package/build/server/chunks/exports-CJ0Q5XmL.js.map +0 -1
- package/build/server/chunks/index2-DAxIoAO-.js +0 -36
- package/build/server/chunks/index2-DAxIoAO-.js.map +0 -1
- package/build/server/chunks/jsonl-parser-dmZU_Hyu.js +0 -137
- package/build/server/chunks/jsonl-parser-dmZU_Hyu.js.map +0 -1
- package/build/server/chunks/library-apns-BHxLmuIx.js.map +0 -1
- package/build/server/chunks/markdown-Bxrl3cCF.js +0 -1241
- package/build/server/chunks/markdown-Bxrl3cCF.js.map +0 -1
- package/build/server/chunks/pty-manager-C0FhBiVq.js.map +0 -1
- package/build/server/chunks/stores-D0HorpgL.js +0 -36
- package/build/server/chunks/stores-D0HorpgL.js.map +0 -1
|
@@ -1,19 +1,8 @@
|
|
|
1
1
|
// In-memory notification history store.
|
|
2
2
|
// Same pattern as pending-requests.ts — suitable for single-instance deployments.
|
|
3
3
|
|
|
4
|
-
export
|
|
5
|
-
|
|
6
|
-
data?: Record<string, unknown>;
|
|
7
|
-
error?: string;
|
|
8
|
-
id: string;
|
|
9
|
-
message: string;
|
|
10
|
-
project?: string;
|
|
11
|
-
source?: string;
|
|
12
|
-
status: 'failed' | 'filtered' | 'sent';
|
|
13
|
-
timestamp: string;
|
|
14
|
-
title: string;
|
|
15
|
-
tool?: string;
|
|
16
|
-
}
|
|
4
|
+
export type { NotificationRecord } from '$generated/types';
|
|
5
|
+
import type { NotificationRecord } from '$generated/types';
|
|
17
6
|
|
|
18
7
|
const MAX_HISTORY = 100;
|
|
19
8
|
|
|
@@ -1,18 +1,8 @@
|
|
|
1
|
+
import type { NotificationSession } from '$generated/types';
|
|
2
|
+
|
|
1
3
|
import { getNotifications, type NotificationRecord } from './notification-history';
|
|
2
4
|
|
|
3
|
-
export
|
|
4
|
-
duration: number; // seconds
|
|
5
|
-
endTime: string;
|
|
6
|
-
eventCount: number;
|
|
7
|
-
events: NotificationRecord[];
|
|
8
|
-
filesModified: string[];
|
|
9
|
-
id: string;
|
|
10
|
-
project: string;
|
|
11
|
-
runtime: string;
|
|
12
|
-
startTime: string;
|
|
13
|
-
status: 'active' | 'complete';
|
|
14
|
-
toolsUsed: string[];
|
|
15
|
-
}
|
|
5
|
+
export type Session = NotificationSession;
|
|
16
6
|
|
|
17
7
|
const SESSION_GAP_MS = 30 * 60 * 1000; // 30 min gap = new session
|
|
18
8
|
const ACTIVE_THRESHOLD_MS = 5 * 60 * 1000; // active if last event < 5 min ago
|
|
@@ -1,14 +1,9 @@
|
|
|
1
1
|
// Shared in-memory store for pending permission requests.
|
|
2
2
|
// Used by /api/notify (creates entries) and /api/response (reads/updates).
|
|
3
3
|
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
decision: 'allow' | 'deny' | null;
|
|
8
|
-
sessionId: string;
|
|
9
|
-
toolInput: Record<string, unknown>;
|
|
10
|
-
toolName: string;
|
|
11
|
-
}
|
|
4
|
+
import type { PendingRequest } from '$generated/types';
|
|
5
|
+
|
|
6
|
+
export type { PendingRequest };
|
|
12
7
|
|
|
13
8
|
const MAX_AGE_MS = 5 * 60 * 1000; // 5 minutes
|
|
14
9
|
|
|
@@ -7,12 +7,13 @@ import type {
|
|
|
7
7
|
SentDetail,
|
|
8
8
|
} from '$generated/types';
|
|
9
9
|
|
|
10
|
-
//
|
|
11
|
-
//
|
|
10
|
+
// Composite types built from generated primitives. These use arrays and
|
|
11
|
+
// union constructs that type-crafter does not emit, so they stay as local
|
|
12
|
+
// definitions.
|
|
12
13
|
|
|
13
14
|
export interface LibraryResult {
|
|
14
|
-
failed: LibraryFailedItem[]
|
|
15
|
-
sent: LibrarySentItem[]
|
|
15
|
+
failed: LibraryFailedItem[];
|
|
16
|
+
sent: LibrarySentItem[];
|
|
16
17
|
}
|
|
17
18
|
|
|
18
19
|
export interface NotificationPayload {
|
|
@@ -6,8 +6,9 @@ export type { ExitCallback, OutputCallback } from './runner';
|
|
|
6
6
|
// Types generated by type-crafter
|
|
7
7
|
export type { CLIOptions };
|
|
8
8
|
|
|
9
|
-
// Types not
|
|
10
|
-
//
|
|
9
|
+
// Types defined in YAML spec (cli.yaml) but not generated by type-crafter
|
|
10
|
+
// because they contain $ref or array constructs.
|
|
11
|
+
// TODO: Remove once type-crafter supports these constructs.
|
|
11
12
|
export interface CLICommand {
|
|
12
13
|
args: string[];
|
|
13
14
|
name: string;
|
|
@@ -30,15 +30,17 @@ export async function sendFCMNotification(
|
|
|
30
30
|
},
|
|
31
31
|
data: {
|
|
32
32
|
body: payload.body || payload.message || '',
|
|
33
|
-
category:
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
33
|
+
category:
|
|
34
|
+
payload.category ??
|
|
35
|
+
(typeof payload.data?.category === 'string' ? payload.data.category : ''),
|
|
36
|
+
project: typeof payload.data?.project === 'string' ? payload.data.project : '',
|
|
37
|
+
requestId: typeof payload.data?.requestId === 'string' ? payload.data.requestId : '',
|
|
38
|
+
source: typeof payload.data?.source === 'string' ? payload.data.source : '',
|
|
37
39
|
timestamp: new Date().toISOString(),
|
|
38
40
|
title: payload.title,
|
|
39
41
|
toolInput: payload.data?.toolInput ? JSON.stringify(payload.data.toolInput) : '',
|
|
40
|
-
toolName: payload.data?.toolName ?
|
|
41
|
-
type: payload.data?.type ?
|
|
42
|
+
toolName: typeof payload.data?.toolName === 'string' ? payload.data.toolName : '',
|
|
43
|
+
type: typeof payload.data?.type === 'string' ? payload.data.type : '',
|
|
42
44
|
},
|
|
43
45
|
token: deviceToken,
|
|
44
46
|
};
|
|
@@ -14,12 +14,12 @@ import type { ConversationMessage, MessagePart } from './types';
|
|
|
14
14
|
* These are control/metadata entries that don't represent conversation content.
|
|
15
15
|
*/
|
|
16
16
|
export const SKIP_EVENT_TYPES = new Set([
|
|
17
|
-
'system',
|
|
18
17
|
'config',
|
|
19
|
-
'summary',
|
|
20
|
-
'result',
|
|
21
18
|
'heartbeat',
|
|
22
19
|
'metadata',
|
|
20
|
+
'result',
|
|
21
|
+
'summary',
|
|
22
|
+
'system',
|
|
23
23
|
]);
|
|
24
24
|
|
|
25
25
|
/**
|
|
@@ -44,6 +44,15 @@ export function getSessionConversation(
|
|
|
44
44
|
}
|
|
45
45
|
}
|
|
46
46
|
|
|
47
|
+
// If no explicit offset, return the LAST `limit` messages (most recent conversation)
|
|
48
|
+
if (offset === 0 && messages.length > limit) {
|
|
49
|
+
let startIdx = messages.length - limit;
|
|
50
|
+
// Adjust to start at a 'user' message boundary so we don't clip mid-turn
|
|
51
|
+
while (startIdx > 0 && startIdx < messages.length && messages[startIdx].role !== 'user') {
|
|
52
|
+
startIdx--;
|
|
53
|
+
}
|
|
54
|
+
return messages.slice(startIdx);
|
|
55
|
+
}
|
|
47
56
|
return messages.slice(offset, offset + limit);
|
|
48
57
|
} catch (error) {
|
|
49
58
|
console.error('[sessions] Failed to parse session JSONL:', error);
|
|
@@ -74,8 +83,6 @@ export function listProjectsWithSessions(): ProjectGroup[] {
|
|
|
74
83
|
|
|
75
84
|
for (const dir of projectDirs) {
|
|
76
85
|
const projectDir = path.join(CLAUDE_PROJECTS_DIR, dir);
|
|
77
|
-
// Decode project path (fallback, prefer session's projectPath)
|
|
78
|
-
const decodedPath = dir.startsWith('-') ? dir.replace(/-/g, '/') : `/${dir.replace(/-/g, '/')}`;
|
|
79
86
|
|
|
80
87
|
// Get sessions for this project
|
|
81
88
|
const sessions = listSessionsForProject(projectDir);
|
|
@@ -86,10 +93,12 @@ export function listProjectsWithSessions(): ProjectGroup[] {
|
|
|
86
93
|
// Sort sessions by modified desc
|
|
87
94
|
sessions.sort((a, b) => new Date(b.modified).getTime() - new Date(a.modified).getTime());
|
|
88
95
|
|
|
89
|
-
//
|
|
96
|
+
// Prefer projectPath from session index, then cwd from JSONL, then decoded dir name
|
|
90
97
|
const realPath =
|
|
91
98
|
sessions.find((s) => s.projectPath && !s.projectPath.includes('.claude/projects'))
|
|
92
|
-
?.projectPath ||
|
|
99
|
+
?.projectPath ||
|
|
100
|
+
readCwdFromProjectDir(projectDir, sessions) ||
|
|
101
|
+
(dir.startsWith('-') ? dir.replace(/-/g, '/') : `/${dir.replace(/-/g, '/')}`);
|
|
93
102
|
const pathSegments = realPath.split('/').filter(Boolean);
|
|
94
103
|
const projectName = pathSegments.slice(-2).join('/');
|
|
95
104
|
|
|
@@ -122,7 +131,8 @@ function cleanTitle(prompt: string): string {
|
|
|
122
131
|
.replace(/<command-args>.*?<\/command-args>/gs, '')
|
|
123
132
|
.replace(/<local-command-caveat>.*?<\/local-command-caveat>/gs, '')
|
|
124
133
|
.replace(/<local-command-stdout>.*?<\/local-command-stdout>/gs, '')
|
|
125
|
-
.replace(/<system-reminder>.*?<\/system-reminder>/gs, '')
|
|
134
|
+
.replace(/<system-reminder>.*?<\/system-reminder>/gs, '')
|
|
135
|
+
.replace(/<task-notification>.*?<\/task-notification>/gs, '');
|
|
126
136
|
|
|
127
137
|
// Iteratively strip tags until none remain (prevents reconstructed tags like "<scr" + "ipt>")
|
|
128
138
|
let prev = '';
|
|
@@ -217,27 +227,33 @@ function listSessionsForProject(projectDir: string): SessionInfo[] {
|
|
|
217
227
|
let messageCount = 0;
|
|
218
228
|
try {
|
|
219
229
|
const content = fs.readFileSync(filePath, 'utf-8');
|
|
220
|
-
// Count user + assistant messages for the
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
}
|
|
230
|
+
// Count user + assistant messages by searching each line for the type field.
|
|
231
|
+
// The type field may appear anywhere on the line (after parentUuid, isSidechain, etc.)
|
|
232
|
+
// so a prefix-only check is not reliable with the current JSONL format.
|
|
233
|
+
let countPos = 0;
|
|
234
|
+
while (countPos < content.length) {
|
|
235
|
+
const nl = content.indexOf('\n', countPos);
|
|
236
|
+
const lineEnd = nl === -1 ? content.length : nl;
|
|
237
|
+
const line = content.substring(countPos, lineEnd);
|
|
238
|
+
if (line.includes('"type":"user"') || line.includes('"type":"assistant"')) {messageCount++;}
|
|
239
|
+
if (nl === -1) {break;}
|
|
240
|
+
countPos = nl + 1;
|
|
232
241
|
}
|
|
233
242
|
// Find the first real user message (skip system caveats, commands, tool results)
|
|
243
|
+
const lines = content.split('\n');
|
|
234
244
|
for (const line of lines) {
|
|
235
|
-
if (!line.trim()) {
|
|
245
|
+
if (!line.trim()) {
|
|
246
|
+
continue;
|
|
247
|
+
}
|
|
236
248
|
try {
|
|
237
249
|
const entry = JSON.parse(line);
|
|
238
|
-
if (entry.type !== 'user') {
|
|
250
|
+
if (entry.type !== 'user') {
|
|
251
|
+
continue;
|
|
252
|
+
}
|
|
239
253
|
const msg = entry.message;
|
|
240
|
-
if (!msg?.content) {
|
|
254
|
+
if (!msg?.content) {
|
|
255
|
+
continue;
|
|
256
|
+
}
|
|
241
257
|
|
|
242
258
|
// Extract text from content (can be string or array of blocks)
|
|
243
259
|
let text = '';
|
|
@@ -256,14 +272,22 @@ function listSessionsForProject(projectDir: string): SessionInfo[] {
|
|
|
256
272
|
}
|
|
257
273
|
}
|
|
258
274
|
|
|
259
|
-
if (!text) {
|
|
275
|
+
if (!text) {
|
|
276
|
+
continue;
|
|
277
|
+
}
|
|
260
278
|
|
|
261
279
|
// Skip system-injected caveats and command outputs
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
280
|
+
// Keep aligned with cleanTitle() tag stripping
|
|
281
|
+
if (
|
|
282
|
+
text.startsWith('<local-command') ||
|
|
283
|
+
text.startsWith('<command-name>') ||
|
|
284
|
+
text.startsWith('<command-message>') ||
|
|
285
|
+
text.startsWith('<command-args>') ||
|
|
286
|
+
text.startsWith('<local-command-stdout>') ||
|
|
287
|
+
text.startsWith('<local-command-caveat>') ||
|
|
288
|
+
text.startsWith('<system-reminder>') ||
|
|
289
|
+
text.startsWith('<task-notification>')
|
|
290
|
+
) {
|
|
267
291
|
continue;
|
|
268
292
|
}
|
|
269
293
|
|
|
@@ -299,3 +323,39 @@ function listSessionsForProject(projectDir: string): SessionInfo[] {
|
|
|
299
323
|
return [];
|
|
300
324
|
}
|
|
301
325
|
}
|
|
326
|
+
|
|
327
|
+
function readCwdFromProjectDir(projectDir: string, sessions: SessionInfo[]): string {
|
|
328
|
+
for (const session of sessions) {
|
|
329
|
+
try {
|
|
330
|
+
const filePath = path.join(projectDir, `${session.id}.jsonl`);
|
|
331
|
+
if (!fs.existsSync(filePath)) {
|
|
332
|
+
continue;
|
|
333
|
+
}
|
|
334
|
+
// Only read the first 4KB — cwd appears on line 1
|
|
335
|
+
const fd = fs.openSync(filePath, 'r');
|
|
336
|
+
let firstChunk: string;
|
|
337
|
+
try {
|
|
338
|
+
const buf = Buffer.alloc(4096);
|
|
339
|
+
const bytesRead = fs.readSync(fd, buf, 0, 4096, 0);
|
|
340
|
+
firstChunk = buf.toString('utf-8', 0, bytesRead);
|
|
341
|
+
} finally {
|
|
342
|
+
fs.closeSync(fd);
|
|
343
|
+
}
|
|
344
|
+
const firstLine = firstChunk.split('\n')[0];
|
|
345
|
+
if (!firstLine.trim()) {
|
|
346
|
+
continue;
|
|
347
|
+
}
|
|
348
|
+
try {
|
|
349
|
+
const entry = JSON.parse(firstLine) as Record<string, unknown>;
|
|
350
|
+
if (typeof entry.cwd === 'string' && entry.cwd) {
|
|
351
|
+
return entry.cwd;
|
|
352
|
+
}
|
|
353
|
+
} catch {
|
|
354
|
+
// skip malformed first line
|
|
355
|
+
}
|
|
356
|
+
} catch {
|
|
357
|
+
// skip unreadable files
|
|
358
|
+
}
|
|
359
|
+
}
|
|
360
|
+
return '';
|
|
361
|
+
}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import * as path from 'path';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Resolve the path to the OpenCode SQLite database.
|
|
5
|
+
*
|
|
6
|
+
* Checks in this order:
|
|
7
|
+
* 1. XDG_DATA_HOME/opencode/opencode.db (honours XDG override)
|
|
8
|
+
* 2. ~/Library/Application Support/opencode/opencode.db (legacy macOS path)
|
|
9
|
+
* 3. ~/.local/share/opencode/opencode.db (XDG default)
|
|
10
|
+
*/
|
|
11
|
+
export function resolveOpenCodeDbPath(): string {
|
|
12
|
+
const home = process.env.HOME || '';
|
|
13
|
+
|
|
14
|
+
// 1. If XDG_DATA_HOME is explicitly set, use it
|
|
15
|
+
if (process.env.XDG_DATA_HOME) {
|
|
16
|
+
return path.join(process.env.XDG_DATA_HOME, 'opencode', 'opencode.db');
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
// 2. Legacy macOS path (~/Library/Application Support/opencode/)
|
|
20
|
+
if (process.platform === 'darwin') {
|
|
21
|
+
return path.join(home, 'Library', 'Application Support', 'opencode', 'opencode.db');
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
// 3. XDG default (~/.local/share/opencode/)
|
|
25
|
+
return path.join(home, '.local', 'share', 'opencode', 'opencode.db');
|
|
26
|
+
}
|
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
import Database from 'better-sqlite3';
|
|
2
2
|
import * as crypto from 'crypto';
|
|
3
3
|
import * as fs from 'fs';
|
|
4
|
-
import * as path from 'path';
|
|
5
4
|
|
|
6
5
|
function shortHash(input: string): string {
|
|
7
6
|
return crypto.createHash('sha256').update(input).digest('hex').slice(0, 8);
|
|
@@ -9,18 +8,14 @@ function shortHash(input: string): string {
|
|
|
9
8
|
|
|
10
9
|
import type { ConversationMessage, MessagePart, ProjectGroup, SessionInfo } from './types';
|
|
11
10
|
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
'share',
|
|
16
|
-
'opencode',
|
|
17
|
-
'opencode.db'
|
|
18
|
-
);
|
|
11
|
+
import { resolveOpenCodeDbPath } from './opencode-db-path';
|
|
12
|
+
|
|
13
|
+
const OPENCODE_DB_PATH = resolveOpenCodeDbPath();
|
|
19
14
|
|
|
20
15
|
export function getOpenCodeConversation(
|
|
21
16
|
sessionId: string,
|
|
22
17
|
offset = 0,
|
|
23
|
-
limit =
|
|
18
|
+
limit = 200
|
|
24
19
|
): ConversationMessage[] {
|
|
25
20
|
const db = getDb();
|
|
26
21
|
if (!db) {
|
|
@@ -28,15 +23,18 @@ export function getOpenCodeConversation(
|
|
|
28
23
|
}
|
|
29
24
|
|
|
30
25
|
try {
|
|
31
|
-
// Get messages
|
|
26
|
+
// Get the LAST `limit` messages (most recent conversation)
|
|
27
|
+
// by using a subquery to reverse the order
|
|
32
28
|
const messages = db
|
|
33
29
|
.prepare(
|
|
34
30
|
`
|
|
35
|
-
SELECT id, session_id, time_created, data
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
31
|
+
SELECT id, session_id, time_created, data FROM (
|
|
32
|
+
SELECT id, session_id, time_created, data
|
|
33
|
+
FROM message
|
|
34
|
+
WHERE session_id = ?
|
|
35
|
+
ORDER BY time_created DESC
|
|
36
|
+
LIMIT ? OFFSET ?
|
|
37
|
+
) ORDER BY time_created ASC
|
|
40
38
|
`
|
|
41
39
|
)
|
|
42
40
|
.all(sessionId, limit, offset) as {
|
|
@@ -0,0 +1,103 @@
|
|
|
1
|
+
import { readdirSync, readFileSync } from 'fs';
|
|
2
|
+
import { homedir } from 'os';
|
|
3
|
+
import { join } from 'path';
|
|
4
|
+
|
|
5
|
+
// ---------------------------------------------------------------------------
|
|
6
|
+
// Types
|
|
7
|
+
// ---------------------------------------------------------------------------
|
|
8
|
+
|
|
9
|
+
export interface DetectedProcess {
|
|
10
|
+
command: 'claude' | 'opencode';
|
|
11
|
+
cwd: string;
|
|
12
|
+
kind: string;
|
|
13
|
+
pid: number;
|
|
14
|
+
projectPath: string;
|
|
15
|
+
sessionId: string;
|
|
16
|
+
startedAt: number;
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
interface ClaudeSessionFile {
|
|
20
|
+
cwd: string;
|
|
21
|
+
entrypoint: string;
|
|
22
|
+
kind: string;
|
|
23
|
+
pid: number;
|
|
24
|
+
sessionId: string;
|
|
25
|
+
startedAt: number;
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
// ---------------------------------------------------------------------------
|
|
29
|
+
// Helpers
|
|
30
|
+
// ---------------------------------------------------------------------------
|
|
31
|
+
|
|
32
|
+
/** Encode a cwd path to the Claude Code project directory format. */
|
|
33
|
+
function cwdToProjectPath(cwd: string): string {
|
|
34
|
+
return cwd.replace(/\//g, '-');
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
/** Check if a process with the given PID is alive. */
|
|
38
|
+
function isProcessAlive(pid: number): boolean {
|
|
39
|
+
try {
|
|
40
|
+
process.kill(pid, 0);
|
|
41
|
+
return true;
|
|
42
|
+
} catch {
|
|
43
|
+
return false;
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
// ---------------------------------------------------------------------------
|
|
48
|
+
// Main detector
|
|
49
|
+
// ---------------------------------------------------------------------------
|
|
50
|
+
|
|
51
|
+
const CLAUDE_SESSIONS_DIR = join(homedir(), '.claude', 'sessions');
|
|
52
|
+
|
|
53
|
+
/**
|
|
54
|
+
* Scan ~/.claude/sessions/*.json to find running Claude Code processes.
|
|
55
|
+
* Each file is named <PID>.json and contains:
|
|
56
|
+
* { pid, sessionId, cwd, startedAt, kind, entrypoint }
|
|
57
|
+
*
|
|
58
|
+
* For each file we verify the PID is still alive via process.kill(pid, 0).
|
|
59
|
+
*/
|
|
60
|
+
export function detectRunningAISessions(): DetectedProcess[] {
|
|
61
|
+
const results: DetectedProcess[] = [];
|
|
62
|
+
|
|
63
|
+
// --- Claude Code sessions ---
|
|
64
|
+
try {
|
|
65
|
+
const files = readdirSync(CLAUDE_SESSIONS_DIR).filter((f) => f.endsWith('.json'));
|
|
66
|
+
|
|
67
|
+
for (const file of files) {
|
|
68
|
+
try {
|
|
69
|
+
const raw = readFileSync(join(CLAUDE_SESSIONS_DIR, file), 'utf-8');
|
|
70
|
+
const data = JSON.parse(raw) as ClaudeSessionFile;
|
|
71
|
+
|
|
72
|
+
if (!data.pid || !data.sessionId || !data.cwd) {
|
|
73
|
+
continue;
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
if (!isProcessAlive(data.pid)) {
|
|
77
|
+
continue;
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
results.push({
|
|
81
|
+
command: 'claude',
|
|
82
|
+
cwd: data.cwd,
|
|
83
|
+
kind: data.kind || 'interactive',
|
|
84
|
+
pid: data.pid,
|
|
85
|
+
projectPath: cwdToProjectPath(data.cwd),
|
|
86
|
+
sessionId: data.sessionId,
|
|
87
|
+
startedAt: data.startedAt || 0,
|
|
88
|
+
});
|
|
89
|
+
} catch {
|
|
90
|
+
// Skip malformed or unreadable files
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
} catch {
|
|
94
|
+
// ~/.claude/sessions/ may not exist — that's fine
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
// Sort by startedAt descending (most recent first)
|
|
98
|
+
results.sort((a, b) => b.startedAt - a.startedAt);
|
|
99
|
+
|
|
100
|
+
// TODO: Add OpenCode process detection (check running opencode processes or query SQLite DB)
|
|
101
|
+
|
|
102
|
+
return results;
|
|
103
|
+
}
|
|
@@ -1,33 +1,22 @@
|
|
|
1
|
+
// Re-export generated types that match 1:1
|
|
2
|
+
export type { MessageRole, ProjectGroup, SessionInfo } from '$generated/types';
|
|
3
|
+
import type { MessageRole } from '$generated/types';
|
|
4
|
+
|
|
5
|
+
// ── Local interfaces ─────────────────────────────────────────────────
|
|
6
|
+
// These remain local because the generated versions differ structurally:
|
|
7
|
+
// generated MessagePart uses wrapper classes (CMessagePartTextPart, etc.)
|
|
8
|
+
// and part types use `type: string` instead of string literals needed
|
|
9
|
+
// for discriminated unions. Declared as interfaces per ESLint rules.
|
|
10
|
+
|
|
1
11
|
export interface ConversationMessage {
|
|
2
12
|
id: string;
|
|
3
13
|
parts: MessagePart[];
|
|
4
|
-
role:
|
|
14
|
+
role: MessageRole;
|
|
5
15
|
timestamp: string;
|
|
6
16
|
}
|
|
7
17
|
|
|
8
18
|
export type MessagePart = TextPart | ThinkingPart | ToolResultPart | ToolUsePart;
|
|
9
19
|
|
|
10
|
-
export interface ProjectGroup {
|
|
11
|
-
fullPath: string;
|
|
12
|
-
id: string;
|
|
13
|
-
lastModified: string;
|
|
14
|
-
name: string;
|
|
15
|
-
sessionCount: number;
|
|
16
|
-
sessions: SessionInfo[];
|
|
17
|
-
}
|
|
18
|
-
|
|
19
|
-
export interface SessionInfo {
|
|
20
|
-
created: string;
|
|
21
|
-
gitBranch: string;
|
|
22
|
-
id: string;
|
|
23
|
-
messageCount: number;
|
|
24
|
-
modified: string;
|
|
25
|
-
projectPath: string;
|
|
26
|
-
source: 'claude-code' | 'opencode';
|
|
27
|
-
summary: string;
|
|
28
|
-
title: string;
|
|
29
|
-
}
|
|
30
|
-
|
|
31
20
|
export interface TextPart {
|
|
32
21
|
content: string;
|
|
33
22
|
type: 'text';
|