@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,243 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Test script for CLIRunner
|
|
3
|
+
* Run with: npx tsx scripts/test-runner.ts
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
import pty, { type IPty } from 'node-pty';
|
|
7
|
+
|
|
8
|
+
interface ExitCallback {
|
|
9
|
+
(code: number, signal?: number): void;
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
interface OutputCallback {
|
|
13
|
+
(data: string): void;
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
interface RunnerConfig {
|
|
17
|
+
args?: string[];
|
|
18
|
+
cols?: number;
|
|
19
|
+
command: string;
|
|
20
|
+
cwd?: string;
|
|
21
|
+
rows?: number;
|
|
22
|
+
useLoginShell?: boolean;
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
class CLIRunner {
|
|
26
|
+
private config: Required<Omit<RunnerConfig, 'useLoginShell'>> & {
|
|
27
|
+
useLoginShell: boolean;
|
|
28
|
+
env: NodeJS.ProcessEnv;
|
|
29
|
+
};
|
|
30
|
+
private onExitCallback: null | ExitCallback = null;
|
|
31
|
+
private onOutputCallback: null | OutputCallback = null;
|
|
32
|
+
private process: IPty | null = null;
|
|
33
|
+
|
|
34
|
+
constructor(config: RunnerConfig) {
|
|
35
|
+
this.config = {
|
|
36
|
+
args: config.args ?? [],
|
|
37
|
+
cols: config.cols ?? 80,
|
|
38
|
+
command: config.command,
|
|
39
|
+
cwd: config.cwd ?? process.cwd(),
|
|
40
|
+
env: process.env,
|
|
41
|
+
rows: config.rows ?? 30,
|
|
42
|
+
useLoginShell: config.useLoginShell ?? true,
|
|
43
|
+
};
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
onExit(callback: ExitCallback): this {
|
|
47
|
+
this.onExitCallback = callback;
|
|
48
|
+
return this;
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
onOutput(callback: OutputCallback): this {
|
|
52
|
+
this.onOutputCallback = callback;
|
|
53
|
+
return this;
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
start(): this {
|
|
57
|
+
if (this.process) {
|
|
58
|
+
throw new Error('Process already running');
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
const { command, args, cwd, env, cols, rows, useLoginShell } = this.config;
|
|
62
|
+
|
|
63
|
+
if (useLoginShell) {
|
|
64
|
+
const shell = process.env.SHELL || '/bin/zsh';
|
|
65
|
+
const shellEscape = (arg: string): string => `'${arg.replace(/'/g, "'\\''")}'`;
|
|
66
|
+
const fullCommand = [command, ...args].map(shellEscape).join(' ');
|
|
67
|
+
this.process = pty.spawn(shell, ['-l', '-c', fullCommand], {
|
|
68
|
+
cols,
|
|
69
|
+
cwd,
|
|
70
|
+
env,
|
|
71
|
+
name: 'xterm-color',
|
|
72
|
+
rows,
|
|
73
|
+
});
|
|
74
|
+
} else {
|
|
75
|
+
this.process = pty.spawn(command, args, {
|
|
76
|
+
cols,
|
|
77
|
+
cwd,
|
|
78
|
+
env,
|
|
79
|
+
name: 'xterm-color',
|
|
80
|
+
rows,
|
|
81
|
+
});
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
this.process.onData((data) => {
|
|
85
|
+
this.onOutputCallback?.(data);
|
|
86
|
+
});
|
|
87
|
+
|
|
88
|
+
this.process.onExit(({ exitCode, signal }) => {
|
|
89
|
+
this.onExitCallback?.(exitCode, signal);
|
|
90
|
+
this.process = null;
|
|
91
|
+
});
|
|
92
|
+
|
|
93
|
+
return this;
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
ctrlC(): this {
|
|
97
|
+
return this.write('\x03');
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
ctrlD(): this {
|
|
101
|
+
return this.write('\x04');
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
enter(): this {
|
|
105
|
+
return this.write('\r');
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
isRunning(): boolean {
|
|
109
|
+
return this.process !== null;
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
stop(): void {
|
|
113
|
+
if (this.process) {
|
|
114
|
+
this.process.kill();
|
|
115
|
+
this.process = null;
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
type(text: string): this {
|
|
120
|
+
return this.write(text);
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
write(data: string): this {
|
|
124
|
+
this.process?.write(data);
|
|
125
|
+
return this;
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
function sleep(ms: number): Promise<void> {
|
|
130
|
+
return new Promise((resolve) => setTimeout(resolve, ms));
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
// Test with echo command
|
|
134
|
+
async function testWithEcho() {
|
|
135
|
+
console.log('=== Testing CLIRunner with echo ===\n');
|
|
136
|
+
|
|
137
|
+
const runner = new CLIRunner({
|
|
138
|
+
command: 'echo',
|
|
139
|
+
args: ['Hello from CLIRunner!'],
|
|
140
|
+
useLoginShell: false,
|
|
141
|
+
});
|
|
142
|
+
|
|
143
|
+
runner.onOutput((data) => {
|
|
144
|
+
process.stdout.write(`๐ค Output: ${data}`);
|
|
145
|
+
});
|
|
146
|
+
|
|
147
|
+
runner.onExit((code) => {
|
|
148
|
+
console.log(`\nโ
Process exited with code ${code}`);
|
|
149
|
+
});
|
|
150
|
+
|
|
151
|
+
runner.start();
|
|
152
|
+
await sleep(1000);
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
// Test with interactive bash
|
|
156
|
+
async function testWithBash() {
|
|
157
|
+
console.log('\n=== Testing CLIRunner with bash ===\n');
|
|
158
|
+
|
|
159
|
+
const runner = new CLIRunner({
|
|
160
|
+
command: 'bash',
|
|
161
|
+
useLoginShell: false,
|
|
162
|
+
});
|
|
163
|
+
|
|
164
|
+
runner.onOutput((data) => {
|
|
165
|
+
process.stdout.write(data);
|
|
166
|
+
});
|
|
167
|
+
|
|
168
|
+
runner.onExit((code) => {
|
|
169
|
+
console.log(`\nโ
Bash exited with code ${code}`);
|
|
170
|
+
});
|
|
171
|
+
|
|
172
|
+
runner.start();
|
|
173
|
+
|
|
174
|
+
await sleep(500);
|
|
175
|
+
runner.type('echo "Hello from bash!"');
|
|
176
|
+
runner.enter();
|
|
177
|
+
|
|
178
|
+
await sleep(500);
|
|
179
|
+
runner.type('pwd');
|
|
180
|
+
runner.enter();
|
|
181
|
+
|
|
182
|
+
await sleep(500);
|
|
183
|
+
runner.type('exit');
|
|
184
|
+
runner.enter();
|
|
185
|
+
|
|
186
|
+
await sleep(1000);
|
|
187
|
+
}
|
|
188
|
+
|
|
189
|
+
// Test with node REPL
|
|
190
|
+
async function testWithNode() {
|
|
191
|
+
console.log('\n=== Testing CLIRunner with node REPL ===\n');
|
|
192
|
+
|
|
193
|
+
const runner = new CLIRunner({
|
|
194
|
+
command: 'node',
|
|
195
|
+
useLoginShell: false,
|
|
196
|
+
});
|
|
197
|
+
|
|
198
|
+
runner.onOutput((data) => {
|
|
199
|
+
process.stdout.write(data);
|
|
200
|
+
});
|
|
201
|
+
|
|
202
|
+
runner.onExit((code) => {
|
|
203
|
+
console.log(`\nโ
Node exited with code ${code}`);
|
|
204
|
+
});
|
|
205
|
+
|
|
206
|
+
runner.start();
|
|
207
|
+
|
|
208
|
+
await sleep(500);
|
|
209
|
+
runner.type('console.log("Hello from Node REPL!")');
|
|
210
|
+
runner.enter();
|
|
211
|
+
|
|
212
|
+
await sleep(300);
|
|
213
|
+
runner.type('2 + 2');
|
|
214
|
+
runner.enter();
|
|
215
|
+
|
|
216
|
+
await sleep(300);
|
|
217
|
+
runner.type('const msg = "CLIRunner works!"');
|
|
218
|
+
runner.enter();
|
|
219
|
+
|
|
220
|
+
await sleep(300);
|
|
221
|
+
runner.type('msg');
|
|
222
|
+
runner.enter();
|
|
223
|
+
|
|
224
|
+
await sleep(300);
|
|
225
|
+
runner.ctrlD(); // Exit node
|
|
226
|
+
|
|
227
|
+
await sleep(500);
|
|
228
|
+
}
|
|
229
|
+
|
|
230
|
+
async function main() {
|
|
231
|
+
try {
|
|
232
|
+
await testWithEcho();
|
|
233
|
+
await testWithBash();
|
|
234
|
+
await testWithNode();
|
|
235
|
+
console.log('\nโ
All tests completed!');
|
|
236
|
+
process.exit(0);
|
|
237
|
+
} catch (error) {
|
|
238
|
+
console.error('โ Test failed:', error);
|
|
239
|
+
process.exit(1);
|
|
240
|
+
}
|
|
241
|
+
}
|
|
242
|
+
|
|
243
|
+
main();
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
#!/bin/bash
|
|
2
|
+
|
|
3
|
+
# Vercel Environment Variable Setup Commands
|
|
4
|
+
# Run these commands if you have Vercel CLI installed
|
|
5
|
+
|
|
6
|
+
echo "๐ง Vercel Environment Variable Setup Commands"
|
|
7
|
+
echo "=============================================="
|
|
8
|
+
echo ""
|
|
9
|
+
echo "If you have Vercel CLI installed, run these commands:"
|
|
10
|
+
echo ""
|
|
11
|
+
|
|
12
|
+
echo "# 1. API Authentication"
|
|
13
|
+
echo "vercel env add API_KEY"
|
|
14
|
+
echo "# Enter: YOUR_API_KEY_HERE (from .env file)"
|
|
15
|
+
echo ""
|
|
16
|
+
|
|
17
|
+
echo "# 2. APNs Key ID"
|
|
18
|
+
echo "vercel env add APNS_KEY_ID"
|
|
19
|
+
echo "# Enter: YOUR_APNS_KEY_ID_HERE (from .env file)"
|
|
20
|
+
echo ""
|
|
21
|
+
|
|
22
|
+
echo "# 3. APNs Team ID"
|
|
23
|
+
echo "vercel env add APNS_TEAM_ID"
|
|
24
|
+
echo "# Enter: YOUR_APNS_TEAM_ID_HERE (from .env file)"
|
|
25
|
+
echo ""
|
|
26
|
+
|
|
27
|
+
echo "# 4. APNs Bundle ID"
|
|
28
|
+
echo "vercel env add APNS_BUNDLE_ID"
|
|
29
|
+
echo "# Enter: YOUR_BUNDLE_ID_HERE (from .env file)"
|
|
30
|
+
echo ""
|
|
31
|
+
|
|
32
|
+
echo "# 5. APNs Private Key (Base64)"
|
|
33
|
+
echo "vercel env add APNS_KEY_BASE64"
|
|
34
|
+
echo "# Enter: YOUR_BASE64_APNS_KEY_HERE (extract from .env between BEGIN/END PRIVATE KEY)"
|
|
35
|
+
echo ""
|
|
36
|
+
|
|
37
|
+
echo "# 6. Device Token (Optional)"
|
|
38
|
+
echo "vercel env add DEVICE_TOKEN"
|
|
39
|
+
echo "# Enter: YOUR_DEVICE_TOKEN_HERE (from iOS app or .env file)"
|
|
40
|
+
echo ""
|
|
41
|
+
|
|
42
|
+
echo "# 7. Environment"
|
|
43
|
+
echo "vercel env add NODE_ENV"
|
|
44
|
+
echo "# Enter: production"
|
|
45
|
+
echo ""
|
|
46
|
+
|
|
47
|
+
echo "# 8. Redeploy after adding variables"
|
|
48
|
+
echo "vercel --prod"
|
|
49
|
+
echo ""
|
|
50
|
+
|
|
51
|
+
echo "๐ Manual Setup (if CLI not available):"
|
|
52
|
+
echo "1. Go to https://vercel.com/dashboard"
|
|
53
|
+
echo "2. Select your 'shooter' project"
|
|
54
|
+
echo "3. Go to Settings > Environment Variables"
|
|
55
|
+
echo "4. Add each variable with values shown above"
|
|
56
|
+
echo "5. Redeploy the application"
|
|
57
|
+
echo ""
|
|
58
|
+
|
|
59
|
+
echo "๐งช Test after setup:"
|
|
60
|
+
echo "./tests/test-production.sh"
|
package/server.ts
ADDED
|
@@ -0,0 +1,139 @@
|
|
|
1
|
+
// Custom server entry point โ run with `npx tsx server.ts`.
|
|
2
|
+
// Wraps the SvelteKit build output with a WebSocket server for terminal I/O,
|
|
3
|
+
// live session streaming, and a global event bus. NOT compiled by SvelteKit.
|
|
4
|
+
|
|
5
|
+
// Load .env into process.env before anything else (adapter-node reads process.env at runtime).
|
|
6
|
+
import 'dotenv/config';
|
|
7
|
+
|
|
8
|
+
import { createServer, type Server } from 'http';
|
|
9
|
+
import { WebSocketServer, type WebSocket } from 'ws';
|
|
10
|
+
|
|
11
|
+
import { handler } from './build/handler.js';
|
|
12
|
+
import { validateTicket } from './src/lib/modules/server/ws/ticket-store.js';
|
|
13
|
+
import { setupWebSocketHandlers } from './src/lib/modules/server/ws/server.js';
|
|
14
|
+
import { startKeepalive, stopKeepalive } from './src/lib/modules/server/ws/keepalive.js';
|
|
15
|
+
import { setPtyManager as setTerminalHandlerPtyManager } from './src/lib/modules/server/ws/terminal-handler.js';
|
|
16
|
+
import {
|
|
17
|
+
setPtyManager as setSessionHandlerPtyManager,
|
|
18
|
+
setSessionWatcher,
|
|
19
|
+
} from './src/lib/modules/server/ws/session-handler.js';
|
|
20
|
+
import { ptyManager } from './src/lib/modules/server/terminal/pty-manager.js';
|
|
21
|
+
import { sessionWatcher } from './src/lib/modules/server/terminal/session-watcher.js';
|
|
22
|
+
import { openCodeWatcher } from './src/lib/modules/server/terminal/opencode-watcher.js';
|
|
23
|
+
import type { ConversationMessage } from './src/lib/modules/server/sessions/types.js';
|
|
24
|
+
|
|
25
|
+
// โโ Adapters โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
|
|
26
|
+
// The WS handlers define their own duck-typed interfaces (PtyManagerLike,
|
|
27
|
+
// SessionWatcherLike) that differ slightly from the real singletons'
|
|
28
|
+
// public APIs. Thin adapters bridge the gap without modifying either side.
|
|
29
|
+
|
|
30
|
+
/** Adapt PtyManager (`.get()`) to the handlers' expected `.getTerminal()`. */
|
|
31
|
+
const ptyManagerAdapter = {
|
|
32
|
+
getTerminal(id: string) {
|
|
33
|
+
return ptyManager.get(id) ?? undefined;
|
|
34
|
+
},
|
|
35
|
+
attach(id: string, ws: WebSocket) {
|
|
36
|
+
return ptyManager.attach(id, ws);
|
|
37
|
+
},
|
|
38
|
+
detach(id: string, ws: WebSocket) {
|
|
39
|
+
return ptyManager.detach(id, ws);
|
|
40
|
+
},
|
|
41
|
+
};
|
|
42
|
+
|
|
43
|
+
/**
|
|
44
|
+
* Adapt SessionWatcher (`.watch()` + `.getHistory()`) to the session
|
|
45
|
+
* handler's expected `.subscribe()` + `.getHistory()` interface.
|
|
46
|
+
*
|
|
47
|
+
* Both watchers now deliver ConversationMessage[] โ the adapter just
|
|
48
|
+
* routes to the correct watcher based on the session key format.
|
|
49
|
+
*/
|
|
50
|
+
const sessionWatcherAdapter = {
|
|
51
|
+
getHistory(sessionFile: string) {
|
|
52
|
+
// Check if this is an OpenCode session ID (not a file path)
|
|
53
|
+
if (!sessionFile.includes('/') && !sessionFile.includes('.jsonl')) {
|
|
54
|
+
return openCodeWatcher.getHistory(sessionFile);
|
|
55
|
+
}
|
|
56
|
+
return sessionWatcher.getHistory(sessionFile);
|
|
57
|
+
},
|
|
58
|
+
subscribe(sessionFile: string, callback: Parameters<typeof sessionWatcher.watch>[1]) {
|
|
59
|
+
if (!sessionFile.includes('/') && !sessionFile.includes('.jsonl')) {
|
|
60
|
+
openCodeWatcher.watch(sessionFile, callback as (messages: ConversationMessage[]) => void);
|
|
61
|
+
return () => openCodeWatcher.stop(sessionFile, callback as (messages: ConversationMessage[]) => void);
|
|
62
|
+
}
|
|
63
|
+
sessionWatcher.watch(sessionFile, callback);
|
|
64
|
+
return () => sessionWatcher.stop(sessionFile);
|
|
65
|
+
},
|
|
66
|
+
};
|
|
67
|
+
|
|
68
|
+
// โโ Wire singletons into WebSocket handlers โโโโโโโโโโโโโโโโโโโโโโโโโโ
|
|
69
|
+
|
|
70
|
+
// The adapters bridge the gap between the real singletons' public APIs and
|
|
71
|
+
// the duck-typed interfaces expected by each WS handler.
|
|
72
|
+
setTerminalHandlerPtyManager(ptyManagerAdapter);
|
|
73
|
+
setSessionHandlerPtyManager(ptyManagerAdapter);
|
|
74
|
+
setSessionWatcher(sessionWatcherAdapter);
|
|
75
|
+
|
|
76
|
+
// Recover persisted terminals before accepting connections
|
|
77
|
+
await ptyManager.reconnectAll();
|
|
78
|
+
|
|
79
|
+
// โโ HTTP server wrapping SvelteKit โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
|
|
80
|
+
|
|
81
|
+
const server: Server = createServer(handler);
|
|
82
|
+
|
|
83
|
+
// โโ WebSocket server (noServer mode โ we handle upgrades manually) โโโ
|
|
84
|
+
|
|
85
|
+
const wss = new WebSocketServer({ noServer: true });
|
|
86
|
+
|
|
87
|
+
server.on('upgrade', (request, socket, head) => {
|
|
88
|
+
const url = new URL(request.url || '', `http://${request.headers.host}`);
|
|
89
|
+
const ticket = url.searchParams.get('ticket');
|
|
90
|
+
|
|
91
|
+
if (!validateTicket(ticket)) {
|
|
92
|
+
socket.write('HTTP/1.1 401 Unauthorized\r\n\r\n');
|
|
93
|
+
socket.destroy();
|
|
94
|
+
return;
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
// Delegate routing to the WS server module which inspects the pathname
|
|
98
|
+
// and dispatches to terminal, session, or events handlers.
|
|
99
|
+
setupWebSocketHandlers(wss, request, socket, head);
|
|
100
|
+
});
|
|
101
|
+
|
|
102
|
+
// โโ Start keepalive pings (30s interval, keeps Cloudflare Tunnel alive) โโ
|
|
103
|
+
|
|
104
|
+
startKeepalive();
|
|
105
|
+
|
|
106
|
+
// โโ Listen โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
|
|
107
|
+
|
|
108
|
+
const port = parseInt(process.env.PORT || '3000', 10);
|
|
109
|
+
|
|
110
|
+
server.listen(port, () => {
|
|
111
|
+
console.log(`Shooter server running on http://localhost:${port}`);
|
|
112
|
+
});
|
|
113
|
+
|
|
114
|
+
// โโ Graceful shutdown โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
|
|
115
|
+
|
|
116
|
+
function shutdown(signal: string): void {
|
|
117
|
+
console.log(`\n${signal} received โ shutting downโฆ`);
|
|
118
|
+
|
|
119
|
+
stopKeepalive();
|
|
120
|
+
ptyManager.disconnectAll();
|
|
121
|
+
sessionWatcher.stopAll();
|
|
122
|
+
openCodeWatcher.stopAll();
|
|
123
|
+
|
|
124
|
+
wss.close(() => {
|
|
125
|
+
server.close(() => {
|
|
126
|
+
console.log('Shooter server stopped.');
|
|
127
|
+
process.exit(0);
|
|
128
|
+
});
|
|
129
|
+
});
|
|
130
|
+
|
|
131
|
+
// Force exit if graceful shutdown takes too long (10 seconds)
|
|
132
|
+
setTimeout(() => {
|
|
133
|
+
console.error('Graceful shutdown timed out โ forcing exit.');
|
|
134
|
+
process.exit(1);
|
|
135
|
+
}, 10_000).unref();
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
process.on('SIGTERM', () => shutdown('SIGTERM'));
|
|
139
|
+
process.on('SIGINT', () => shutdown('SIGINT'));
|