@juspay/shooter 1.0.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 +1431 -0
- package/.claude/settings.json +162 -0
- package/README.md +515 -0
- package/bin/shooter.cjs +141 -0
- package/build/client/_app/immutable/assets/0.CM9Hl6d-.css +1 -0
- 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/2.CAShZ7lQ.css +1 -0
- package/build/client/_app/immutable/assets/2.CAShZ7lQ.css.br +1 -0
- package/build/client/_app/immutable/assets/2.CAShZ7lQ.css.gz +0 -0
- package/build/client/_app/immutable/assets/3.C0uFg0IS.css +1 -0
- 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 +1 -0
- 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 +1 -0
- 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 +1 -0
- 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 +1 -0
- 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 +1 -0
- 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 +1 -0
- 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/assets/xterm.DFuMZ0ql.css +1 -0
- package/build/client/_app/immutable/assets/xterm.DFuMZ0ql.css.br +0 -0
- package/build/client/_app/immutable/assets/xterm.DFuMZ0ql.css.gz +0 -0
- package/build/client/_app/immutable/chunks/BNJphC1q.js +56 -0
- 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/BTGVxaYV.js +9 -0
- package/build/client/_app/immutable/chunks/BTGVxaYV.js.br +0 -0
- package/build/client/_app/immutable/chunks/BTGVxaYV.js.gz +0 -0
- package/build/client/_app/immutable/chunks/BlxrFPDK.js +1 -0
- package/build/client/_app/immutable/chunks/BlxrFPDK.js.br +0 -0
- package/build/client/_app/immutable/chunks/BlxrFPDK.js.gz +0 -0
- package/build/client/_app/immutable/chunks/Bvk7mfPM.js +1 -0
- 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 +1 -0
- 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 +1 -0
- 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 +1 -0
- 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 +6 -0
- 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 +11 -0
- 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 +1 -0
- 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 +1 -0
- 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/DLu6yJIZ.js +1 -0
- package/build/client/_app/immutable/chunks/DLu6yJIZ.js.br +0 -0
- package/build/client/_app/immutable/chunks/DLu6yJIZ.js.gz +0 -0
- package/build/client/_app/immutable/chunks/Dkkpz_4D.js +126 -0
- 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 +1 -0
- 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/PPVm8Dsz.js +1 -0
- package/build/client/_app/immutable/chunks/PPVm8Dsz.js.br +0 -0
- package/build/client/_app/immutable/chunks/PPVm8Dsz.js.gz +0 -0
- package/build/client/_app/immutable/chunks/RpcNruLP.js +2 -0
- 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 +1 -0
- 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 +1 -0
- 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 +2 -0
- 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 +1 -0
- 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 +1 -0
- 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 +1 -0
- 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 +1 -0
- 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 +3 -0
- 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 +1 -0
- 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 +1 -0
- 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 +2 -0
- 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 +2 -0
- 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/_app/version.json +1 -0
- package/build/client/_app/version.json.br +0 -0
- package/build/client/_app/version.json.gz +0 -0
- package/build/client/app-icon.png +0 -0
- package/build/client/apple-touch-icon.png +0 -0
- package/build/client/favicon.png +0 -0
- package/build/client/favicon.svg +10 -0
- package/build/client/favicon.svg.br +0 -0
- package/build/client/favicon.svg.gz +0 -0
- package/build/client/manifest.webmanifest +1 -0
- package/build/client/pwa-192x192.png +0 -0
- package/build/client/pwa-512x512.png +0 -0
- package/build/client/registerSW.js +1 -0
- package/build/client/registerSW.js.br +0 -0
- package/build/client/registerSW.js.gz +0 -0
- package/build/client/sw.js +222 -0
- package/build/client/sw.js.br +0 -0
- package/build/client/sw.js.gz +0 -0
- package/build/client/workbox-5119daf5.js +3395 -0
- package/build/client/workbox-5119daf5.js.br +0 -0
- package/build/client/workbox-5119daf5.js.gz +0 -0
- package/build/env.js +94 -0
- package/build/handler.js +1494 -0
- package/build/index.js +345 -0
- package/build/pty-holder.cjs +510 -0
- package/build/server/chunks/0-q2IUp76Y.js +9 -0
- package/build/server/chunks/0-q2IUp76Y.js.map +1 -0
- package/build/server/chunks/1-CU50G5wZ.js +9 -0
- package/build/server/chunks/1-CU50G5wZ.js.map +1 -0
- package/build/server/chunks/2-D01t9s8T.js +9 -0
- package/build/server/chunks/2-D01t9s8T.js.map +1 -0
- package/build/server/chunks/3-5PUQ04wC.js +9 -0
- package/build/server/chunks/3-5PUQ04wC.js.map +1 -0
- package/build/server/chunks/4-e7gywnSG.js +9 -0
- package/build/server/chunks/4-e7gywnSG.js.map +1 -0
- package/build/server/chunks/5-CA1SA6KZ.js +9 -0
- package/build/server/chunks/5-CA1SA6KZ.js.map +1 -0
- package/build/server/chunks/6-71H221sV.js +9 -0
- package/build/server/chunks/6-71H221sV.js.map +1 -0
- package/build/server/chunks/7-Bo-vmdyz.js +9 -0
- package/build/server/chunks/7-Bo-vmdyz.js.map +1 -0
- package/build/server/chunks/_layout.svelte-SFHOxs74.js +132 -0
- package/build/server/chunks/_layout.svelte-SFHOxs74.js.map +1 -0
- package/build/server/chunks/_page.svelte-B4w-2wD-.js +120 -0
- package/build/server/chunks/_page.svelte-B4w-2wD-.js.map +1 -0
- package/build/server/chunks/_page.svelte-B_qAXjkh.js +213 -0
- package/build/server/chunks/_page.svelte-B_qAXjkh.js.map +1 -0
- package/build/server/chunks/_page.svelte-CsF1_TRG.js +50 -0
- package/build/server/chunks/_page.svelte-CsF1_TRG.js.map +1 -0
- package/build/server/chunks/_page.svelte-DJC6U-P0.js +68 -0
- package/build/server/chunks/_page.svelte-DJC6U-P0.js.map +1 -0
- package/build/server/chunks/_page.svelte-DQ6HBtsz.js +407 -0
- package/build/server/chunks/_page.svelte-DQ6HBtsz.js.map +1 -0
- package/build/server/chunks/_page.svelte-LbhhjP21.js +148 -0
- package/build/server/chunks/_page.svelte-LbhhjP21.js.map +1 -0
- package/build/server/chunks/_server.ts-BL2FGb5Z.js +387 -0
- package/build/server/chunks/_server.ts-BL2FGb5Z.js.map +1 -0
- package/build/server/chunks/_server.ts-BgdjBZco.js +47 -0
- package/build/server/chunks/_server.ts-BgdjBZco.js.map +1 -0
- package/build/server/chunks/_server.ts-BihKSdj_.js +59 -0
- package/build/server/chunks/_server.ts-BihKSdj_.js.map +1 -0
- package/build/server/chunks/_server.ts-BjOJsoy4.js +63 -0
- package/build/server/chunks/_server.ts-BjOJsoy4.js.map +1 -0
- package/build/server/chunks/_server.ts-C29xzfaw.js +77 -0
- package/build/server/chunks/_server.ts-C29xzfaw.js.map +1 -0
- package/build/server/chunks/_server.ts-CPa6DgIt.js +71 -0
- package/build/server/chunks/_server.ts-CPa6DgIt.js.map +1 -0
- package/build/server/chunks/_server.ts-CbDRDIoP.js +36 -0
- package/build/server/chunks/_server.ts-CbDRDIoP.js.map +1 -0
- package/build/server/chunks/_server.ts-Cl1OEWL4.js +54 -0
- package/build/server/chunks/_server.ts-Cl1OEWL4.js.map +1 -0
- package/build/server/chunks/_server.ts-ColfDHW8.js +60 -0
- package/build/server/chunks/_server.ts-ColfDHW8.js.map +1 -0
- package/build/server/chunks/_server.ts-Cv_OrRuL.js +494 -0
- package/build/server/chunks/_server.ts-Cv_OrRuL.js.map +1 -0
- package/build/server/chunks/_server.ts-D4MNi4cD.js +25 -0
- package/build/server/chunks/_server.ts-D4MNi4cD.js.map +1 -0
- package/build/server/chunks/_server.ts-DRVbgm6k.js +125 -0
- package/build/server/chunks/_server.ts-DRVbgm6k.js.map +1 -0
- package/build/server/chunks/_server.ts-DfajWaqh.js +39 -0
- package/build/server/chunks/_server.ts-DfajWaqh.js.map +1 -0
- package/build/server/chunks/_server.ts-y9-WYDMa.js +35 -0
- package/build/server/chunks/_server.ts-y9-WYDMa.js.map +1 -0
- package/build/server/chunks/auth-CEgFis71.js +32 -0
- package/build/server/chunks/auth-CEgFis71.js.map +1 -0
- package/build/server/chunks/client-CxCatAKr.js +255 -0
- package/build/server/chunks/client-CxCatAKr.js.map +1 -0
- package/build/server/chunks/error.svelte-BqdwMWdK.js +26 -0
- package/build/server/chunks/error.svelte-BqdwMWdK.js.map +1 -0
- package/build/server/chunks/exports-CJ0Q5XmL.js +4081 -0
- package/build/server/chunks/exports-CJ0Q5XmL.js.map +1 -0
- package/build/server/chunks/index2-DAxIoAO-.js +36 -0
- package/build/server/chunks/index2-DAxIoAO-.js.map +1 -0
- package/build/server/chunks/jsonl-parser-dmZU_Hyu.js +137 -0
- package/build/server/chunks/jsonl-parser-dmZU_Hyu.js.map +1 -0
- package/build/server/chunks/library-apns-BHxLmuIx.js +104 -0
- package/build/server/chunks/library-apns-BHxLmuIx.js.map +1 -0
- package/build/server/chunks/markdown-Bxrl3cCF.js +1241 -0
- package/build/server/chunks/markdown-Bxrl3cCF.js.map +1 -0
- package/build/server/chunks/pending-requests-D8UiTw7L.js +44 -0
- package/build/server/chunks/pending-requests-D8UiTw7L.js.map +1 -0
- package/build/server/chunks/pty-manager-C0FhBiVq.js +1697 -0
- package/build/server/chunks/pty-manager-C0FhBiVq.js.map +1 -0
- package/build/server/chunks/shared-server-BDY8jh20.js +200 -0
- package/build/server/chunks/shared-server-BDY8jh20.js.map +1 -0
- package/build/server/chunks/stores-D0HorpgL.js +36 -0
- package/build/server/chunks/stores-D0HorpgL.js.map +1 -0
- package/build/server/index.js +6466 -0
- package/build/server/index.js.map +1 -0
- package/build/server/manifest.js +184 -0
- package/build/server/manifest.js.map +1 -0
- package/build/shims.js +32 -0
- package/package.json +94 -0
- package/scripts/clipboard-shims/wl-paste +48 -0
- package/scripts/clipboard-shims/xclip +31 -0
- package/scripts/install.sh +477 -0
- package/scripts/setup-node-pty.sh +63 -0
- package/scripts/setup.cjs +571 -0
- package/scripts/test-runner.ts +243 -0
- package/scripts/vercel-env-commands.sh +60 -0
- package/server.ts +139 -0
- package/src/app.css +1835 -0
- package/src/app.d.ts +31 -0
- package/src/app.html +24 -0
- package/src/generated/types/APN.ts +305 -0
- package/src/generated/types/CLI.ts +52 -0
- package/src/generated/types/JWT.ts +92 -0
- package/src/generated/types/Terminal.ts +2736 -0
- package/src/generated/types/index.ts +6 -0
- package/src/lib/assets/icons/alert-triangle.svg +5 -0
- package/src/lib/assets/icons/bell.svg +4 -0
- package/src/lib/assets/icons/check-circle.svg +4 -0
- package/src/lib/assets/icons/file.svg +4 -0
- package/src/lib/assets/icons/folder.svg +3 -0
- package/src/lib/assets/icons/play.svg +3 -0
- package/src/lib/assets/icons/refresh.svg +4 -0
- package/src/lib/assets/icons/settings.svg +4 -0
- package/src/lib/assets/icons/terminal.svg +1 -0
- package/src/lib/assets/icons/tool.svg +3 -0
- package/src/lib/assets/icons/x-circle.svg +5 -0
- package/src/lib/modules/client/common/Card.svelte +26 -0
- package/src/lib/modules/client/common/EmptyState.svelte +36 -0
- package/src/lib/modules/client/common/Icon.svelte +61 -0
- package/src/lib/modules/client/common/StatusBadge.svelte +38 -0
- package/src/lib/modules/client/common/cache.ts +31 -0
- package/src/lib/modules/client/common/config-guard.ts +18 -0
- package/src/lib/modules/client/common/index.ts +12 -0
- package/src/lib/modules/client/common/markdown.ts +23 -0
- package/src/lib/modules/client/common/native-bridge.ts +50 -0
- package/src/lib/modules/client/common/time.ts +22 -0
- package/src/lib/modules/client/common/tool-title.ts +28 -0
- package/src/lib/modules/client/terminal/ChatView.svelte +400 -0
- package/src/lib/modules/client/terminal/CommandPalette.svelte +60 -0
- package/src/lib/modules/client/terminal/ConnectionStatus.svelte +99 -0
- package/src/lib/modules/client/terminal/LaunchSheet.svelte +294 -0
- package/src/lib/modules/client/terminal/QuickKeys.svelte +71 -0
- package/src/lib/modules/client/terminal/ShortcutsHelp.svelte +79 -0
- package/src/lib/modules/client/terminal/keyboard-shortcuts.ts +70 -0
- package/src/lib/modules/client/terminal/xterm-wrapper.ts +243 -0
- package/src/lib/modules/server/apn/library-apns.ts +137 -0
- package/src/lib/modules/server/apn/notification-history.ts +35 -0
- package/src/lib/modules/server/apn/notification-sessions.ts +117 -0
- package/src/lib/modules/server/apn/pending-requests.ts +65 -0
- package/src/lib/modules/server/apn/types.ts +51 -0
- package/src/lib/modules/server/auth.ts +34 -0
- package/src/lib/modules/server/cli/index.ts +79 -0
- package/src/lib/modules/server/cli/runner.ts +162 -0
- package/src/lib/modules/server/fcm/fcm-service.ts +72 -0
- package/src/lib/modules/server/sessions/jsonl-parser.ts +197 -0
- package/src/lib/modules/server/sessions/jsonl-reader.ts +301 -0
- package/src/lib/modules/server/sessions/opencode-reader.ts +264 -0
- package/src/lib/modules/server/sessions/types.ts +53 -0
- package/src/lib/modules/server/terminal/holder-client.ts +273 -0
- package/src/lib/modules/server/terminal/opencode-watcher.ts +661 -0
- package/src/lib/modules/server/terminal/pty-holder.cjs +510 -0
- package/src/lib/modules/server/terminal/pty-manager.ts +1012 -0
- package/src/lib/modules/server/terminal/session-watcher.ts +320 -0
- package/src/lib/modules/server/terminal/terminal-store.ts +198 -0
- package/src/lib/modules/server/ws/events-handler.ts +73 -0
- package/src/lib/modules/server/ws/keepalive.ts +108 -0
- package/src/lib/modules/server/ws/server.ts +93 -0
- package/src/lib/modules/server/ws/session-handler.ts +462 -0
- package/src/lib/modules/server/ws/terminal-handler.ts +197 -0
- package/src/lib/modules/server/ws/ticket-store.ts +58 -0
- package/src/lib/theme.css +529 -0
- package/src/lib/types/config.ts +6 -0
- package/src/routes/+layout.svelte +218 -0
- package/src/routes/+page.svelte +261 -0
- package/src/routes/api/debug/+server.ts +33 -0
- package/src/routes/api/device-token/+server.ts +85 -0
- package/src/routes/api/health/+server.ts +100 -0
- package/src/routes/api/notify/+server.ts +418 -0
- package/src/routes/api/qr-config/+server.ts +45 -0
- package/src/routes/api/response/+server.ts +73 -0
- package/src/routes/api/sessions/+server.ts +120 -0
- package/src/routes/api/terminals/+server.ts +141 -0
- package/src/routes/api/terminals/[id]/+server.ts +75 -0
- package/src/routes/api/terminals/[id]/paste-image/+server.ts +61 -0
- package/src/routes/api/terminals/[id]/resize/+server.ts +60 -0
- package/src/routes/api/webhook/+server.ts +42 -0
- package/src/routes/api/ws-status/+server.ts +23 -0
- package/src/routes/api/ws-ticket/+server.ts +86 -0
- package/src/routes/config/+page.svelte +600 -0
- package/src/routes/project/+page.svelte +274 -0
- package/src/routes/session/[id]/+page.svelte +434 -0
- package/src/routes/terminals/+page.svelte +618 -0
- package/src/routes/terminals/[id]/+page.svelte +968 -0
- package/svelte.config.js +18 -0
- package/tsconfig.json +14 -0
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
import type { Options as CLIOptions } from '$generated/types';
|
|
2
|
+
|
|
3
|
+
export { CLIRunner, createRunner, sleep } from './runner';
|
|
4
|
+
export type { ExitCallback, OutputCallback } from './runner';
|
|
5
|
+
|
|
6
|
+
// Types generated by type-crafter
|
|
7
|
+
export type { CLIOptions };
|
|
8
|
+
|
|
9
|
+
// Types not yet generated by type-crafter (contain $ref/arrays)
|
|
10
|
+
// TODO: Remove these once type-crafter generates them
|
|
11
|
+
export interface CLICommand {
|
|
12
|
+
args: string[];
|
|
13
|
+
name: string;
|
|
14
|
+
options: CLIOptions;
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
export interface CLIResult {
|
|
18
|
+
error: null | string;
|
|
19
|
+
exitCode: number;
|
|
20
|
+
output: null | string;
|
|
21
|
+
success: boolean;
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
export interface CLIRunnerConfig {
|
|
25
|
+
args: null | string[];
|
|
26
|
+
cols: null | number;
|
|
27
|
+
command: string;
|
|
28
|
+
cwd: null | string;
|
|
29
|
+
rows: null | number;
|
|
30
|
+
useLoginShell: boolean | null;
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
const DEFAULT_OPTIONS: CLIOptions = {
|
|
34
|
+
dryRun: false,
|
|
35
|
+
timeout: null,
|
|
36
|
+
verbose: false,
|
|
37
|
+
};
|
|
38
|
+
|
|
39
|
+
export function createCommand(name: string, args: string[] = []): CLICommand {
|
|
40
|
+
return {
|
|
41
|
+
args,
|
|
42
|
+
name,
|
|
43
|
+
options: { ...DEFAULT_OPTIONS },
|
|
44
|
+
};
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
export function createErrorResult(error: string, exitCode = 1): CLIResult {
|
|
48
|
+
return {
|
|
49
|
+
error,
|
|
50
|
+
exitCode,
|
|
51
|
+
output: null,
|
|
52
|
+
success: false,
|
|
53
|
+
};
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
export function createSuccessResult(output: string): CLIResult {
|
|
57
|
+
return {
|
|
58
|
+
error: null,
|
|
59
|
+
exitCode: 0,
|
|
60
|
+
output,
|
|
61
|
+
success: true,
|
|
62
|
+
};
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
export function formatCommand(command: CLICommand): string {
|
|
66
|
+
const parts = [command.name, ...command.args];
|
|
67
|
+
return parts.join(' ');
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
export function withOptions(command: CLICommand, options: Partial<CLIOptions>): CLICommand {
|
|
71
|
+
return {
|
|
72
|
+
...command,
|
|
73
|
+
options: {
|
|
74
|
+
dryRun: options.dryRun !== undefined ? options.dryRun : command.options.dryRun,
|
|
75
|
+
timeout: options.timeout !== undefined ? options.timeout : command.options.timeout,
|
|
76
|
+
verbose: options.verbose !== undefined ? options.verbose : command.options.verbose,
|
|
77
|
+
},
|
|
78
|
+
};
|
|
79
|
+
}
|
|
@@ -0,0 +1,162 @@
|
|
|
1
|
+
import pty, { type IPty } from 'node-pty';
|
|
2
|
+
|
|
3
|
+
import type { CLIRunnerConfig } from './index';
|
|
4
|
+
|
|
5
|
+
export type ExitCallback = (code: number, signal?: number) => void;
|
|
6
|
+
export type OutputCallback = (data: string) => void;
|
|
7
|
+
|
|
8
|
+
interface InternalConfig {
|
|
9
|
+
args: string[];
|
|
10
|
+
cols: number;
|
|
11
|
+
command: string;
|
|
12
|
+
cwd: string;
|
|
13
|
+
env: NodeJS.ProcessEnv;
|
|
14
|
+
rows: number;
|
|
15
|
+
useLoginShell: boolean;
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
export class CLIRunner {
|
|
19
|
+
private config: InternalConfig;
|
|
20
|
+
private onExitCallback: ExitCallback | null = null;
|
|
21
|
+
private onOutputCallback: null | OutputCallback = null;
|
|
22
|
+
private process: IPty | null = null;
|
|
23
|
+
|
|
24
|
+
constructor(config: CLIRunnerConfig) {
|
|
25
|
+
this.config = {
|
|
26
|
+
args: config.args ?? [],
|
|
27
|
+
cols: config.cols ?? 80,
|
|
28
|
+
command: config.command,
|
|
29
|
+
cwd: config.cwd ?? process.cwd(),
|
|
30
|
+
env: process.env,
|
|
31
|
+
rows: config.rows ?? 30,
|
|
32
|
+
useLoginShell: config.useLoginShell ?? true,
|
|
33
|
+
};
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
ctrlC(): this {
|
|
37
|
+
return this.write('\x03');
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
ctrlD(): this {
|
|
41
|
+
return this.write('\x04');
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
ctrlZ(): this {
|
|
45
|
+
return this.write('\x1a');
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
enter(): this {
|
|
49
|
+
return this.write('\r');
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
escape(): this {
|
|
53
|
+
return this.write('\x1b');
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
isRunning(): boolean {
|
|
57
|
+
return this.process !== null;
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
moveDown(): this {
|
|
61
|
+
return this.write('\x1b[B');
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
moveLeft(): this {
|
|
65
|
+
return this.write('\x1b[D');
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
moveRight(): this {
|
|
69
|
+
return this.write('\x1b[C');
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
moveUp(): this {
|
|
73
|
+
return this.write('\x1b[A');
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
onExit(callback: ExitCallback): this {
|
|
77
|
+
this.onExitCallback = callback;
|
|
78
|
+
return this;
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
onOutput(callback: OutputCallback): this {
|
|
82
|
+
this.onOutputCallback = callback;
|
|
83
|
+
return this;
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
resize(cols: number, rows: number): this {
|
|
87
|
+
this.process?.resize(cols, rows);
|
|
88
|
+
return this;
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
space(): this {
|
|
92
|
+
return this.write(' ');
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
start(): this {
|
|
96
|
+
if (this.process) {
|
|
97
|
+
throw new Error('Process already running');
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
const { args, cols, command, cwd, env, rows, useLoginShell } = this.config;
|
|
101
|
+
|
|
102
|
+
if (useLoginShell) {
|
|
103
|
+
const shell = process.env.SHELL || '/bin/zsh';
|
|
104
|
+
const shellEscape = (arg: string): string => `'${arg.replace(/'/g, "'\\''")}'`;
|
|
105
|
+
const fullCommand = [command, ...args].map(shellEscape).join(' ');
|
|
106
|
+
this.process = pty.spawn(shell, ['-l', '-c', fullCommand], {
|
|
107
|
+
cols,
|
|
108
|
+
cwd,
|
|
109
|
+
env,
|
|
110
|
+
name: 'xterm-color',
|
|
111
|
+
rows,
|
|
112
|
+
});
|
|
113
|
+
} else {
|
|
114
|
+
this.process = pty.spawn(command, args, {
|
|
115
|
+
cols,
|
|
116
|
+
cwd,
|
|
117
|
+
env,
|
|
118
|
+
name: 'xterm-color',
|
|
119
|
+
rows,
|
|
120
|
+
});
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
this.process.onData((data) => {
|
|
124
|
+
this.onOutputCallback?.(data);
|
|
125
|
+
});
|
|
126
|
+
|
|
127
|
+
this.process.onExit(({ exitCode, signal }) => {
|
|
128
|
+
this.onExitCallback?.(exitCode, signal);
|
|
129
|
+
this.process = null;
|
|
130
|
+
});
|
|
131
|
+
|
|
132
|
+
return this;
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
stop(): void {
|
|
136
|
+
if (this.process) {
|
|
137
|
+
this.process.kill();
|
|
138
|
+
this.process = null;
|
|
139
|
+
}
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
tab(): this {
|
|
143
|
+
return this.write('\t');
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
type(text: string): this {
|
|
147
|
+
return this.write(text);
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
write(data: string): this {
|
|
151
|
+
this.process?.write(data);
|
|
152
|
+
return this;
|
|
153
|
+
}
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
export function createRunner(config: CLIRunnerConfig): CLIRunner {
|
|
157
|
+
return new CLIRunner(config);
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
export function sleep(ms: number): Promise<void> {
|
|
161
|
+
return new Promise((resolve) => setTimeout(resolve, ms));
|
|
162
|
+
}
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
import admin from 'firebase-admin';
|
|
2
|
+
|
|
3
|
+
import type { NotificationPayload } from '../apn/types.js';
|
|
4
|
+
|
|
5
|
+
let app: admin.app.App | null = null;
|
|
6
|
+
|
|
7
|
+
export function isFCMConfigured(): boolean {
|
|
8
|
+
return !!(
|
|
9
|
+
process.env.FCM_PROJECT_ID &&
|
|
10
|
+
process.env.FCM_CLIENT_EMAIL &&
|
|
11
|
+
process.env.FCM_PRIVATE_KEY
|
|
12
|
+
);
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
export async function sendFCMNotification(
|
|
16
|
+
deviceToken: string,
|
|
17
|
+
payload: NotificationPayload
|
|
18
|
+
): Promise<{ error?: string; messageId?: string; success: boolean }> {
|
|
19
|
+
try {
|
|
20
|
+
const fcmApp = getApp();
|
|
21
|
+
|
|
22
|
+
// Use DATA-ONLY messages (not notification messages)
|
|
23
|
+
// This is critical: notification messages are auto-displayed by Android
|
|
24
|
+
// and cannot have custom action buttons. Data messages always reach
|
|
25
|
+
// onMessageReceived() giving the app full control.
|
|
26
|
+
const message: admin.messaging.Message = {
|
|
27
|
+
android: {
|
|
28
|
+
priority: 'high', // Ensures delivery even in Doze mode
|
|
29
|
+
ttl: 300000, // 5 minutes TTL (matches pending request expiry)
|
|
30
|
+
},
|
|
31
|
+
data: {
|
|
32
|
+
body: payload.body || payload.message || '',
|
|
33
|
+
category: payload.category ? String(payload.category) : (payload.data?.category ? String(payload.data.category) : ''),
|
|
34
|
+
project: payload.data?.project ? String(payload.data.project) : '',
|
|
35
|
+
requestId: payload.data?.requestId ? String(payload.data.requestId) : '',
|
|
36
|
+
source: payload.data?.source ? String(payload.data.source) : '',
|
|
37
|
+
timestamp: new Date().toISOString(),
|
|
38
|
+
title: payload.title,
|
|
39
|
+
toolInput: payload.data?.toolInput ? JSON.stringify(payload.data.toolInput) : '',
|
|
40
|
+
toolName: payload.data?.toolName ? String(payload.data.toolName) : '',
|
|
41
|
+
type: payload.data?.type ? String(payload.data.type) : '',
|
|
42
|
+
},
|
|
43
|
+
token: deviceToken,
|
|
44
|
+
};
|
|
45
|
+
|
|
46
|
+
const messageId = await admin.messaging(fcmApp).send(message);
|
|
47
|
+
return { messageId, success: true };
|
|
48
|
+
} catch (error) {
|
|
49
|
+
const errorMessage = error instanceof Error ? error.message : String(error);
|
|
50
|
+
console.error('[FCM] Send failed:', errorMessage);
|
|
51
|
+
return { error: errorMessage, success: false };
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
function getApp(): admin.app.App {
|
|
56
|
+
if (!app) {
|
|
57
|
+
const projectId = process.env.FCM_PROJECT_ID;
|
|
58
|
+
const clientEmail = process.env.FCM_CLIENT_EMAIL;
|
|
59
|
+
const privateKey = process.env.FCM_PRIVATE_KEY?.replace(/\\n/g, '\n');
|
|
60
|
+
|
|
61
|
+
if (!projectId || !clientEmail || !privateKey) {
|
|
62
|
+
throw new Error(
|
|
63
|
+
'FCM not configured: missing FCM_PROJECT_ID, FCM_CLIENT_EMAIL, or FCM_PRIVATE_KEY'
|
|
64
|
+
);
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
app = admin.initializeApp({
|
|
68
|
+
credential: admin.credential.cert({ clientEmail, privateKey, projectId }),
|
|
69
|
+
});
|
|
70
|
+
}
|
|
71
|
+
return app;
|
|
72
|
+
}
|
|
@@ -0,0 +1,197 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Shared JSONL parsing utilities for Claude Code session files.
|
|
3
|
+
*
|
|
4
|
+
* Both the REST API (jsonl-reader.ts) and the live file watcher
|
|
5
|
+
* (session-watcher.ts) use these functions to convert raw JSONL lines
|
|
6
|
+
* into ConversationMessage objects. Keeping one canonical parser
|
|
7
|
+
* eliminates drift between the two code paths.
|
|
8
|
+
*/
|
|
9
|
+
|
|
10
|
+
import type { ConversationMessage, MessagePart } from './types';
|
|
11
|
+
|
|
12
|
+
/**
|
|
13
|
+
* Internal event types that should be skipped during parsing.
|
|
14
|
+
* These are control/metadata entries that don't represent conversation content.
|
|
15
|
+
*/
|
|
16
|
+
export const SKIP_EVENT_TYPES = new Set([
|
|
17
|
+
'system',
|
|
18
|
+
'config',
|
|
19
|
+
'summary',
|
|
20
|
+
'result',
|
|
21
|
+
'heartbeat',
|
|
22
|
+
'metadata',
|
|
23
|
+
]);
|
|
24
|
+
|
|
25
|
+
/**
|
|
26
|
+
* Parse a single assistant content block into a MessagePart.
|
|
27
|
+
*/
|
|
28
|
+
export function parseAssistantBlock(block: Record<string, unknown>): MessagePart | null {
|
|
29
|
+
if (!block || typeof block !== 'object') {
|
|
30
|
+
return null;
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
switch (block.type) {
|
|
34
|
+
case 'text':
|
|
35
|
+
return { content: (block.text as string) || '', type: 'text' };
|
|
36
|
+
case 'thinking':
|
|
37
|
+
return { content: (block.thinking as string) || '', type: 'thinking' };
|
|
38
|
+
case 'tool_use':
|
|
39
|
+
return {
|
|
40
|
+
id: (block.id as string) || '',
|
|
41
|
+
input: (block.input as Record<string, unknown>) || {},
|
|
42
|
+
toolName: (block.name as string) || 'Unknown',
|
|
43
|
+
type: 'tool_use',
|
|
44
|
+
};
|
|
45
|
+
default:
|
|
46
|
+
return null;
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
/**
|
|
51
|
+
* Parse a single JSONL line into zero or more ConversationMessage entries.
|
|
52
|
+
*
|
|
53
|
+
* For assistant entries, partial accumulation is handled by the caller
|
|
54
|
+
* using the assistantTurns map. When an assistant entry includes a
|
|
55
|
+
* stop_reason, the accumulated turn is flushed into assistantCompleted.
|
|
56
|
+
*/
|
|
57
|
+
export function parseJsonlLine(
|
|
58
|
+
line: string,
|
|
59
|
+
assistantTurns: Map<string, { parts: MessagePart[]; timestamp: string }>,
|
|
60
|
+
messageIndex: number
|
|
61
|
+
): { assistantCompleted: ConversationMessage[]; messages: ConversationMessage[] } {
|
|
62
|
+
const messages: ConversationMessage[] = [];
|
|
63
|
+
const assistantCompleted: ConversationMessage[] = [];
|
|
64
|
+
|
|
65
|
+
const entry = JSON.parse(line);
|
|
66
|
+
const entryType = entry.type;
|
|
67
|
+
|
|
68
|
+
// Skip known internal event types that don't represent conversation content
|
|
69
|
+
if (SKIP_EVENT_TYPES.has(entryType)) {
|
|
70
|
+
return { assistantCompleted, messages };
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
if (entryType === 'user') {
|
|
74
|
+
const msg = entry.message;
|
|
75
|
+
if (!msg?.content) {
|
|
76
|
+
return { assistantCompleted, messages };
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
const parts: MessagePart[] = [];
|
|
80
|
+
const content = Array.isArray(msg.content) ? msg.content : [msg.content];
|
|
81
|
+
|
|
82
|
+
for (const block of content) {
|
|
83
|
+
if (typeof block === 'string') {
|
|
84
|
+
parts.push({ content: block, type: 'text' });
|
|
85
|
+
} else if (block.type === 'text') {
|
|
86
|
+
parts.push({ content: block.text || '', type: 'text' });
|
|
87
|
+
} else if (block.type === 'tool_result') {
|
|
88
|
+
let output = '';
|
|
89
|
+
if (typeof block.content === 'string') {
|
|
90
|
+
output = block.content;
|
|
91
|
+
} else if (Array.isArray(block.content)) {
|
|
92
|
+
output = block.content
|
|
93
|
+
.filter((c: { type: string }) => c.type === 'text')
|
|
94
|
+
.map((c: { text: string }) => c.text)
|
|
95
|
+
.join('\n');
|
|
96
|
+
}
|
|
97
|
+
if (entry.toolUseResult?.content) {
|
|
98
|
+
const trc = entry.toolUseResult.content;
|
|
99
|
+
if (typeof trc === 'string') {
|
|
100
|
+
output = trc;
|
|
101
|
+
} else if (Array.isArray(trc)) {
|
|
102
|
+
output = trc
|
|
103
|
+
.filter((c: { type: string }) => c.type === 'text')
|
|
104
|
+
.map((c: { text: string }) => c.text)
|
|
105
|
+
.join('\n');
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
parts.push({
|
|
109
|
+
isError: block.is_error || false,
|
|
110
|
+
output: output.slice(0, 2000),
|
|
111
|
+
toolUseId: block.tool_use_id || '',
|
|
112
|
+
type: 'tool_result',
|
|
113
|
+
});
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
if (parts.length > 0 && parts.some((p) => p.type === 'text')) {
|
|
118
|
+
messages.push({
|
|
119
|
+
id: entry.uuid || `user-${messageIndex}`,
|
|
120
|
+
parts: parts.filter((p) => p.type === 'text'),
|
|
121
|
+
role: 'user',
|
|
122
|
+
timestamp: entry.timestamp || '',
|
|
123
|
+
});
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
const toolResults = parts.filter((p) => p.type === 'tool_result');
|
|
127
|
+
if (toolResults.length > 0) {
|
|
128
|
+
messages.push({
|
|
129
|
+
id: `tool-result-${entry.uuid || messageIndex}`,
|
|
130
|
+
parts: toolResults,
|
|
131
|
+
role: 'system',
|
|
132
|
+
timestamp: entry.timestamp || '',
|
|
133
|
+
});
|
|
134
|
+
}
|
|
135
|
+
} else if (entryType === 'assistant') {
|
|
136
|
+
const msg = entry.message;
|
|
137
|
+
if (!msg?.content) {
|
|
138
|
+
return { assistantCompleted, messages };
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
const content = Array.isArray(msg.content) ? msg.content : [msg.content];
|
|
142
|
+
const msgId = msg.id || entry.uuid;
|
|
143
|
+
|
|
144
|
+
for (const block of content) {
|
|
145
|
+
const part = parseAssistantBlock(block);
|
|
146
|
+
if (!part) {
|
|
147
|
+
continue;
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
if (!assistantTurns.has(msgId)) {
|
|
151
|
+
assistantTurns.set(msgId, { parts: [], timestamp: entry.timestamp || '' });
|
|
152
|
+
}
|
|
153
|
+
assistantTurns.get(msgId)!.parts.push(part);
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
if (msg.stop_reason) {
|
|
157
|
+
const turn = assistantTurns.get(msgId);
|
|
158
|
+
if (turn && turn.parts.length > 0) {
|
|
159
|
+
assistantCompleted.push({
|
|
160
|
+
id: msgId,
|
|
161
|
+
parts: turn.parts,
|
|
162
|
+
role: 'assistant',
|
|
163
|
+
timestamp: turn.timestamp,
|
|
164
|
+
});
|
|
165
|
+
assistantTurns.delete(msgId);
|
|
166
|
+
}
|
|
167
|
+
}
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
return { assistantCompleted, messages };
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
/**
|
|
174
|
+
* Parse raw JSONL text into ConversationMessage entries.
|
|
175
|
+
* Handles multi-entry assistant turns that span multiple JSONL lines.
|
|
176
|
+
*/
|
|
177
|
+
export function parseJsonlText(
|
|
178
|
+
text: string,
|
|
179
|
+
assistantTurns: Map<string, { parts: MessagePart[]; timestamp: string }>,
|
|
180
|
+
startIndex: number
|
|
181
|
+
): ConversationMessage[] {
|
|
182
|
+
const lines = text.split('\n').filter((line) => line.trim());
|
|
183
|
+
const allMessages: ConversationMessage[] = [];
|
|
184
|
+
let idx = startIndex;
|
|
185
|
+
|
|
186
|
+
for (const line of lines) {
|
|
187
|
+
try {
|
|
188
|
+
const { assistantCompleted, messages } = parseJsonlLine(line, assistantTurns, idx);
|
|
189
|
+
allMessages.push(...messages, ...assistantCompleted);
|
|
190
|
+
idx++;
|
|
191
|
+
} catch {
|
|
192
|
+
// Skip malformed lines
|
|
193
|
+
}
|
|
194
|
+
}
|
|
195
|
+
|
|
196
|
+
return allMessages;
|
|
197
|
+
}
|