@juspay/shooter 1.0.0 → 1.1.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.DC5pAwP3.css} +1 -1
- package/build/client/_app/immutable/assets/0.DC5pAwP3.css.br +0 -0
- package/build/client/_app/immutable/assets/{0.CM9Hl6d-.css.gz → 0.DC5pAwP3.css.gz} +0 -0
- package/build/client/_app/immutable/assets/2.CAShZ7lQ.css.gz +0 -0
- package/build/client/_app/immutable/assets/3.BoXp0JoS.css +1 -0
- package/build/client/_app/immutable/assets/3.BoXp0JoS.css.br +0 -0
- package/build/client/_app/immutable/assets/3.BoXp0JoS.css.gz +0 -0
- package/build/client/_app/immutable/assets/4.cJuCkJKZ.css.gz +0 -0
- package/build/client/_app/immutable/assets/5.DRjApZQW.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.BCJ1IuMx.css → 7.PyEFVv_s.css} +1 -1
- package/build/client/_app/immutable/assets/7.PyEFVv_s.css.br +0 -0
- package/build/client/_app/immutable/assets/7.PyEFVv_s.css.gz +0 -0
- package/build/client/_app/immutable/assets/ChatView.CsdBAOKx.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/{Cjwk_cGO.js → 50RPd5u3.js} +1 -1
- package/build/client/_app/immutable/chunks/50RPd5u3.js.br +0 -0
- package/build/client/_app/immutable/chunks/50RPd5u3.js.gz +0 -0
- package/build/client/_app/immutable/chunks/BDC7XD4o.js +1 -0
- package/build/client/_app/immutable/chunks/BDC7XD4o.js.br +0 -0
- package/build/client/_app/immutable/chunks/BDC7XD4o.js.gz +0 -0
- package/build/client/_app/immutable/chunks/BTGVxaYV.js.gz +0 -0
- package/build/client/_app/immutable/chunks/BeONA6_G.js +2 -0
- package/build/client/_app/immutable/chunks/BeONA6_G.js.br +0 -0
- package/build/client/_app/immutable/chunks/BeONA6_G.js.gz +0 -0
- package/build/client/_app/immutable/chunks/BlxrFPDK.js.gz +0 -0
- package/build/client/_app/immutable/chunks/BygiiMA0.js +1 -0
- package/build/client/_app/immutable/chunks/BygiiMA0.js.br +0 -0
- package/build/client/_app/immutable/chunks/BygiiMA0.js.gz +0 -0
- package/build/client/_app/immutable/chunks/CGLrx-H5.js.gz +0 -0
- package/build/client/_app/immutable/chunks/CHvUpVYv.js +1 -0
- package/build/client/_app/immutable/chunks/CHvUpVYv.js.br +0 -0
- package/build/client/_app/immutable/chunks/CHvUpVYv.js.gz +0 -0
- package/build/client/_app/immutable/chunks/CbqC9BW7.js +1 -0
- package/build/client/_app/immutable/chunks/CbqC9BW7.js.br +2 -0
- package/build/client/_app/immutable/chunks/CbqC9BW7.js.gz +0 -0
- package/build/client/_app/immutable/chunks/CdL99jkG.js +1 -0
- package/build/client/_app/immutable/chunks/CdL99jkG.js.br +0 -0
- package/build/client/_app/immutable/chunks/CdL99jkG.js.gz +0 -0
- package/build/client/_app/immutable/chunks/ClK4wZbC.js +61 -0
- package/build/client/_app/immutable/chunks/ClK4wZbC.js.br +0 -0
- package/build/client/_app/immutable/chunks/ClK4wZbC.js.gz +0 -0
- package/build/client/_app/immutable/chunks/CojFyTPp.js +1 -0
- package/build/client/_app/immutable/chunks/CojFyTPp.js.br +0 -0
- package/build/client/_app/immutable/chunks/CojFyTPp.js.gz +0 -0
- package/build/client/_app/immutable/chunks/DLu6yJIZ.js.gz +0 -0
- package/build/client/_app/immutable/chunks/DREFAyhX.js +60 -0
- package/build/client/_app/immutable/chunks/DREFAyhX.js.br +0 -0
- package/build/client/_app/immutable/chunks/DREFAyhX.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/K_aHH2KN.js +1 -0
- package/build/client/_app/immutable/chunks/K_aHH2KN.js.br +0 -0
- package/build/client/_app/immutable/chunks/K_aHH2KN.js.gz +0 -0
- package/build/client/_app/immutable/chunks/Ona8oofC.js +1 -0
- package/build/client/_app/immutable/chunks/Ona8oofC.js.br +0 -0
- package/build/client/_app/immutable/chunks/Ona8oofC.js.gz +0 -0
- package/build/client/_app/immutable/chunks/PPVm8Dsz.js.gz +0 -0
- package/build/client/_app/immutable/chunks/tjbnEgXP.js +1 -0
- package/build/client/_app/immutable/chunks/tjbnEgXP.js.br +0 -0
- package/build/client/_app/immutable/chunks/tjbnEgXP.js.gz +0 -0
- package/build/client/_app/immutable/entry/app.anqwe7ZL.js +2 -0
- package/build/client/_app/immutable/entry/app.anqwe7ZL.js.br +0 -0
- package/build/client/_app/immutable/entry/app.anqwe7ZL.js.gz +0 -0
- package/build/client/_app/immutable/entry/start.BV2VRv6h.js +1 -0
- package/build/client/_app/immutable/entry/start.BV2VRv6h.js.br +2 -0
- package/build/client/_app/immutable/entry/start.BV2VRv6h.js.gz +0 -0
- package/build/client/_app/immutable/nodes/0.D0i5MqcI.js +1 -0
- package/build/client/_app/immutable/nodes/0.D0i5MqcI.js.br +0 -0
- package/build/client/_app/immutable/nodes/0.D0i5MqcI.js.gz +0 -0
- package/build/client/_app/immutable/nodes/1.DN5n5c6F.js +1 -0
- package/build/client/_app/immutable/nodes/1.DN5n5c6F.js.br +0 -0
- package/build/client/_app/immutable/nodes/1.DN5n5c6F.js.gz +0 -0
- package/build/client/_app/immutable/nodes/2.BTjkNKZJ.js +1 -0
- package/build/client/_app/immutable/nodes/2.BTjkNKZJ.js.br +0 -0
- package/build/client/_app/immutable/nodes/2.BTjkNKZJ.js.gz +0 -0
- package/build/client/_app/immutable/nodes/3.CEkigHDv.js +3 -0
- package/build/client/_app/immutable/nodes/3.CEkigHDv.js.br +0 -0
- package/build/client/_app/immutable/nodes/3.CEkigHDv.js.gz +0 -0
- package/build/client/_app/immutable/nodes/4.B-8Zsc9k.js +1 -0
- package/build/client/_app/immutable/nodes/4.B-8Zsc9k.js.br +0 -0
- package/build/client/_app/immutable/nodes/4.B-8Zsc9k.js.gz +0 -0
- package/build/client/_app/immutable/nodes/5.shitbtHc.js +1 -0
- package/build/client/_app/immutable/nodes/5.shitbtHc.js.br +0 -0
- package/build/client/_app/immutable/nodes/5.shitbtHc.js.gz +0 -0
- package/build/client/_app/immutable/nodes/6.CB8Q6eH8.js +2 -0
- package/build/client/_app/immutable/nodes/6.CB8Q6eH8.js.br +0 -0
- package/build/client/_app/immutable/nodes/6.CB8Q6eH8.js.gz +0 -0
- package/build/client/_app/immutable/nodes/7.D0CrR6pl.js +2 -0
- package/build/client/_app/immutable/nodes/7.D0CrR6pl.js.br +0 -0
- package/build/client/_app/immutable/nodes/7.D0CrR6pl.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/pty-holder.cjs +37 -8
- package/build/server/chunks/0-Cs1dzfRz.js +9 -0
- package/build/server/chunks/{0-q2IUp76Y.js.map → 0-Cs1dzfRz.js.map} +1 -1
- package/build/server/chunks/1-BCSX7oED.js +9 -0
- package/build/server/chunks/{1-CU50G5wZ.js.map → 1-BCSX7oED.js.map} +1 -1
- package/build/server/chunks/2-6gkeO8b4.js +9 -0
- package/build/server/chunks/2-6gkeO8b4.js.map +1 -0
- package/build/server/chunks/3-DH9J9Vsc.js +9 -0
- package/build/server/chunks/3-DH9J9Vsc.js.map +1 -0
- package/build/server/chunks/4-Rzy5TYjl.js +9 -0
- package/build/server/chunks/4-Rzy5TYjl.js.map +1 -0
- package/build/server/chunks/5-D0wB7nfE.js +9 -0
- package/build/server/chunks/5-D0wB7nfE.js.map +1 -0
- package/build/server/chunks/6-DR2ABDPq.js +9 -0
- package/build/server/chunks/6-DR2ABDPq.js.map +1 -0
- package/build/server/chunks/7-D-oQJsia.js +9 -0
- package/build/server/chunks/7-D-oQJsia.js.map +1 -0
- package/build/server/chunks/Button-C7D5W6wV.js +80 -0
- package/build/server/chunks/Button-C7D5W6wV.js.map +1 -0
- package/build/server/chunks/EmptyState-Ci4pSpmY.js +20 -0
- package/build/server/chunks/EmptyState-Ci4pSpmY.js.map +1 -0
- package/build/server/chunks/Icon-DyrkHVnV.js +36 -0
- package/build/server/chunks/Icon-DyrkHVnV.js.map +1 -0
- package/build/server/chunks/Shimmer-BITK6wrm.js +10 -0
- package/build/server/chunks/Shimmer-BITK6wrm.js.map +1 -0
- package/build/server/chunks/_layout.svelte-CO4f8UD7.js +76 -0
- package/build/server/chunks/_layout.svelte-CO4f8UD7.js.map +1 -0
- package/build/server/chunks/_page.svelte-3Cc3NMAP.js +81 -0
- package/build/server/chunks/_page.svelte-3Cc3NMAP.js.map +1 -0
- package/build/server/chunks/_page.svelte-C0p3HsIW.js +46 -0
- package/build/server/chunks/_page.svelte-C0p3HsIW.js.map +1 -0
- package/build/server/chunks/_page.svelte-C6bns9aQ.js +41 -0
- package/build/server/chunks/_page.svelte-C6bns9aQ.js.map +1 -0
- package/build/server/chunks/_page.svelte-CFCONiDK.js +97 -0
- package/build/server/chunks/_page.svelte-CFCONiDK.js.map +1 -0
- package/build/server/chunks/_page.svelte-DskND_G9.js +550 -0
- package/build/server/chunks/_page.svelte-DskND_G9.js.map +1 -0
- package/build/server/chunks/_page.svelte-rTrWmhOp.js +651 -0
- package/build/server/chunks/_page.svelte-rTrWmhOp.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-C29xzfaw.js → _server.ts-C8slOHB0.js} +9 -10
- package/build/server/chunks/_server.ts-C8slOHB0.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-DRVbgm6k.js → _server.ts-CS5H5klP.js} +10 -17
- package/build/server/chunks/_server.ts-CS5H5klP.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-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-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-DhTrdlWH.js +62 -0
- package/build/server/chunks/_server.ts-DhTrdlWH.js.map +1 -0
- package/build/server/chunks/{_server.ts-Cv_OrRuL.js → _server.ts-DpEVfp8W.js} +165 -8
- package/build/server/chunks/_server.ts-DpEVfp8W.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-uHUi-4cd.js} +7 -8
- package/build/server/chunks/_server.ts-uHUi-4cd.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-BYT9c0ig.js +7 -0
- package/build/server/chunks/client-BYT9c0ig.js.map +1 -0
- package/build/server/chunks/client2-BjxIYuno.js +25 -0
- package/build/server/chunks/client2-BjxIYuno.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/error.svelte-BG_yE-Wt.js +27 -0
- package/build/server/chunks/error.svelte-BG_yE-Wt.js.map +1 -0
- package/build/server/chunks/{exports-CJ0Q5XmL.js → index-Cnl871UW.js} +1111 -1634
- package/build/server/chunks/index-Cnl871UW.js.map +1 -0
- package/build/server/chunks/index-server-CUC9Jt7r.js +9 -0
- package/build/server/chunks/index-server-CUC9Jt7r.js.map +1 -0
- package/build/server/chunks/index2-HA3VTH7y.js +58 -0
- package/build/server/chunks/index2-HA3VTH7y.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/{pty-manager-C0FhBiVq.js → pty-manager-DR0Wt2Ac.js} +146 -319
- package/build/server/chunks/pty-manager-DR0Wt2Ac.js.map +1 -0
- package/build/server/chunks/root-DhswcH6o.js +1171 -0
- package/build/server/chunks/root-DhswcH6o.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-2Lellg7t.js +11 -0
- package/build/server/chunks/state.svelte-2Lellg7t.js.map +1 -0
- package/build/server/index.js +1085 -2242
- package/build/server/index.js.map +1 -1
- package/build/server/manifest.js +23 -23
- 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 +139 -43
- package/server.ts +111 -71
- package/src/app.css +12 -3
- package/src/app.d.ts +13 -20
- package/src/app.html +0 -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/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/native-bridge.ts +28 -20
- package/src/lib/modules/client/terminal/ChatView.svelte +46 -23
- package/src/lib/modules/client/terminal/CommandPalette.svelte +3 -2
- package/src/lib/modules/client/terminal/ConnectionStatus.svelte +6 -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 +70 -44
- 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 +60 -15
- 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 +555 -553
- package/src/lib/modules/server/terminal/pty-holder.cjs +37 -8
- package/src/lib/modules/server/terminal/pty-manager.ts +141 -111
- 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 +52 -45
- 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/types/config.ts +1 -6
- package/src/routes/+layout.svelte +66 -31
- package/src/routes/+page.svelte +8 -15
- 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 +69 -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 +3 -1
- package/src/routes/api/terminals/+server.ts +14 -15
- 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 +129 -76
- package/src/routes/project/+page.svelte +7 -28
- package/src/routes/session/[id]/+page.svelte +70 -52
- package/src/routes/terminals/+page.svelte +45 -43
- package/src/routes/terminals/[id]/+page.svelte +198 -91
- package/build/client/_app/immutable/assets/0.CM9Hl6d-.css.br +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/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.br +0 -0
- package/build/client/_app/immutable/assets/7.BCJ1IuMx.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/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.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/1-CU50G5wZ.js +0 -9
- 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
|
@@ -33,8 +33,8 @@ const RUNTIME = IS_OPENCODE ? 'opencode' : 'claude-code';
|
|
|
33
33
|
|
|
34
34
|
// Environment configuration
|
|
35
35
|
const USE_LOCAL = process.env.SHOOTER_USE_LOCAL === 'true';
|
|
36
|
-
const LOCAL_PORT = process.env.SHOOTER_LOCAL_PORT || '
|
|
37
|
-
const REMOTE_BASE_URL = process.env.SHOOTER_API_URL || '';
|
|
36
|
+
const LOCAL_PORT = process.env.SHOOTER_LOCAL_PORT || '54007';
|
|
37
|
+
const REMOTE_BASE_URL = process.env.SHOOTER_API_URL?.trim() || '';
|
|
38
38
|
const LOCAL_BASE_URL = `http://localhost:${LOCAL_PORT}`;
|
|
39
39
|
const BASE_URL = USE_LOCAL ? LOCAL_BASE_URL : REMOTE_BASE_URL;
|
|
40
40
|
const API_URL = `${BASE_URL}/api/notify`;
|
|
@@ -80,28 +80,35 @@ async function hasWebSocketClients() {
|
|
|
80
80
|
const url = `${BASE_URL}/api/ws-status`;
|
|
81
81
|
const protocol = url.startsWith('https') ? https : http;
|
|
82
82
|
return new Promise((resolve) => {
|
|
83
|
-
const req = protocol.request(
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
res
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
83
|
+
const req = protocol.request(
|
|
84
|
+
url,
|
|
85
|
+
{
|
|
86
|
+
method: 'GET',
|
|
87
|
+
headers: { Authorization: `Bearer ${AUTH_KEY}` },
|
|
88
|
+
timeout: 3000,
|
|
89
|
+
},
|
|
90
|
+
(res) => {
|
|
91
|
+
let data = '';
|
|
92
|
+
res.on('data', (chunk) => (data += chunk));
|
|
93
|
+
res.on('end', () => {
|
|
94
|
+
if (res.statusCode === 200) {
|
|
95
|
+
try {
|
|
96
|
+
const parsed = JSON.parse(data);
|
|
97
|
+
resolve(parsed.connectedClients > 0);
|
|
98
|
+
} catch (e) {
|
|
99
|
+
resolve(false);
|
|
100
|
+
}
|
|
101
|
+
} else {
|
|
96
102
|
resolve(false);
|
|
97
103
|
}
|
|
98
|
-
}
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
});
|
|
102
|
-
});
|
|
104
|
+
});
|
|
105
|
+
}
|
|
106
|
+
);
|
|
103
107
|
req.on('error', () => resolve(false));
|
|
104
|
-
req.on('timeout', () => {
|
|
108
|
+
req.on('timeout', () => {
|
|
109
|
+
req.destroy();
|
|
110
|
+
resolve(false);
|
|
111
|
+
});
|
|
105
112
|
req.end();
|
|
106
113
|
});
|
|
107
114
|
} catch (e) {
|
|
@@ -625,26 +632,20 @@ async function handlePermission(event) {
|
|
|
625
632
|
console.error(`=== REGISTERING REQUEST & POLLING VIA WEBSOCKET CHANNEL ===\n`);
|
|
626
633
|
}
|
|
627
634
|
|
|
628
|
-
//
|
|
629
|
-
//
|
|
635
|
+
// Register the pending request but skip the actual push notification —
|
|
636
|
+
// the events channel will broadcast the permission to connected clients.
|
|
630
637
|
result = await sendNotificationAndPoll(
|
|
631
638
|
title,
|
|
632
639
|
body,
|
|
633
640
|
'permission',
|
|
634
641
|
event.source,
|
|
635
642
|
requestId,
|
|
636
|
-
d
|
|
643
|
+
d,
|
|
644
|
+
{ skipPush: true }
|
|
637
645
|
);
|
|
638
646
|
} else {
|
|
639
647
|
// No WebSocket clients — send push notification and poll
|
|
640
|
-
result = await sendNotificationAndPoll(
|
|
641
|
-
title,
|
|
642
|
-
body,
|
|
643
|
-
'permission',
|
|
644
|
-
event.source,
|
|
645
|
-
requestId,
|
|
646
|
-
d
|
|
647
|
-
);
|
|
648
|
+
result = await sendNotificationAndPoll(title, body, 'permission', event.source, requestId, d);
|
|
648
649
|
}
|
|
649
650
|
|
|
650
651
|
if (result && result.decision) {
|
|
@@ -1022,7 +1023,15 @@ function createCompletionMessage(state, projectName) {
|
|
|
1022
1023
|
*
|
|
1023
1024
|
* Returns { decision: 'allow' | 'deny' } or null on timeout.
|
|
1024
1025
|
*/
|
|
1025
|
-
function sendNotificationAndPoll(
|
|
1026
|
+
function sendNotificationAndPoll(
|
|
1027
|
+
title,
|
|
1028
|
+
body,
|
|
1029
|
+
category,
|
|
1030
|
+
source,
|
|
1031
|
+
requestId,
|
|
1032
|
+
eventData,
|
|
1033
|
+
{ skipPush = false } = {}
|
|
1034
|
+
) {
|
|
1026
1035
|
return new Promise((resolve) => {
|
|
1027
1036
|
const timestamp = new Date().toISOString();
|
|
1028
1037
|
|
|
@@ -1030,6 +1039,81 @@ function sendNotificationAndPoll(title, body, category, source, requestId, event
|
|
|
1030
1039
|
const envPrefix = USE_LOCAL ? '[LOCAL]' : '';
|
|
1031
1040
|
const finalTitle = `${runtimePrefix}${envPrefix ? ' ' + envPrefix : ''} ${title}`;
|
|
1032
1041
|
|
|
1042
|
+
// When skipPush is true (WebSocket clients connected), skip the actual
|
|
1043
|
+
// POST to /api/notify but still register the pending request and poll.
|
|
1044
|
+
if (skipPush) {
|
|
1045
|
+
debugLog(
|
|
1046
|
+
`Skipping push notification (WebSocket active), going straight to polling (requestId: ${requestId})`
|
|
1047
|
+
);
|
|
1048
|
+
// Register the pending request on the server so polling finds it.
|
|
1049
|
+
// We still need to POST with waitForResponse so the server creates
|
|
1050
|
+
// the pending-request entry, but we mark it as ws-only.
|
|
1051
|
+
const registerPayload = JSON.stringify({
|
|
1052
|
+
title: finalTitle,
|
|
1053
|
+
message: body,
|
|
1054
|
+
waitForResponse: true,
|
|
1055
|
+
skipPush: true,
|
|
1056
|
+
...(DEVICE_TOKEN && { deviceToken: DEVICE_TOKEN }),
|
|
1057
|
+
data: {
|
|
1058
|
+
category,
|
|
1059
|
+
project: getProjectName(),
|
|
1060
|
+
timestamp,
|
|
1061
|
+
requestId,
|
|
1062
|
+
clientTimestamp: timestamp,
|
|
1063
|
+
source: 'shooter-completion-detector',
|
|
1064
|
+
environment: USE_LOCAL ? 'local' : 'remote',
|
|
1065
|
+
runtime: source,
|
|
1066
|
+
toolName: eventData.tool || '',
|
|
1067
|
+
toolInput: eventData.toolInput || {},
|
|
1068
|
+
sessionId: eventData.sessionId || '',
|
|
1069
|
+
},
|
|
1070
|
+
});
|
|
1071
|
+
|
|
1072
|
+
const registerOptions = {
|
|
1073
|
+
method: 'POST',
|
|
1074
|
+
headers: {
|
|
1075
|
+
'Content-Type': 'application/json',
|
|
1076
|
+
Authorization: `Bearer ${AUTH_KEY}`,
|
|
1077
|
+
'Content-Length': Buffer.byteLength(registerPayload),
|
|
1078
|
+
'User-Agent': `Shooter-Notifier/3.0 ${source}`,
|
|
1079
|
+
},
|
|
1080
|
+
};
|
|
1081
|
+
|
|
1082
|
+
const protocol = API_URL.startsWith('https') ? https : http;
|
|
1083
|
+
const req = protocol.request(API_URL, registerOptions, (res) => {
|
|
1084
|
+
let responseData = '';
|
|
1085
|
+
res.on('data', (chunk) => (responseData += chunk));
|
|
1086
|
+
res.on('end', () => {
|
|
1087
|
+
debugLog(`Pending request registered (skipPush): status=${res.statusCode}`);
|
|
1088
|
+
if (res.statusCode !== 200) {
|
|
1089
|
+
debugLog(
|
|
1090
|
+
`Registration failed (skipPush): ${res.statusCode} - falling through to local dialog`
|
|
1091
|
+
);
|
|
1092
|
+
resolve(null);
|
|
1093
|
+
return;
|
|
1094
|
+
}
|
|
1095
|
+
// Start polling only after successful registration — the WebSocket
|
|
1096
|
+
// events channel will deliver the permission to connected clients.
|
|
1097
|
+
startPolling(requestId, resolve);
|
|
1098
|
+
});
|
|
1099
|
+
});
|
|
1100
|
+
|
|
1101
|
+
req.on('error', (error) => {
|
|
1102
|
+
debugLog(
|
|
1103
|
+
`Register request error (skipPush): ${error.message} - falling through to local dialog`
|
|
1104
|
+
);
|
|
1105
|
+
resolve(null);
|
|
1106
|
+
});
|
|
1107
|
+
|
|
1108
|
+
req.setTimeout(10000, () => {
|
|
1109
|
+
req.destroy(new Error('Request timeout'));
|
|
1110
|
+
});
|
|
1111
|
+
|
|
1112
|
+
req.write(registerPayload);
|
|
1113
|
+
req.end();
|
|
1114
|
+
return;
|
|
1115
|
+
}
|
|
1116
|
+
|
|
1033
1117
|
debugLog(`Sending bidirectional notification: "${finalTitle}" (requestId: ${requestId})`);
|
|
1034
1118
|
|
|
1035
1119
|
const payload = JSON.stringify({
|
package/.claude/settings.json
CHANGED
|
@@ -9,7 +9,7 @@
|
|
|
9
9
|
"hooks": [
|
|
10
10
|
{
|
|
11
11
|
"type": "command",
|
|
12
|
-
"command": "SHOOTER_USE_LOCAL=true SHOOTER_LOCAL_PORT
|
|
12
|
+
"command": "SHOOTER_USE_LOCAL=true SHOOTER_LOCAL_PORT=${SHOOTER_LOCAL_PORT:-54007} API_KEY=$API_KEY node .claude/hooks/notifier.cjs PreToolUse"
|
|
13
13
|
}
|
|
14
14
|
]
|
|
15
15
|
}
|
|
@@ -20,7 +20,7 @@
|
|
|
20
20
|
"hooks": [
|
|
21
21
|
{
|
|
22
22
|
"type": "command",
|
|
23
|
-
"command": "SHOOTER_USE_LOCAL=true SHOOTER_LOCAL_PORT
|
|
23
|
+
"command": "SHOOTER_USE_LOCAL=true SHOOTER_LOCAL_PORT=${SHOOTER_LOCAL_PORT:-54007} API_KEY=$API_KEY node .claude/hooks/notifier.cjs PostToolUse"
|
|
24
24
|
}
|
|
25
25
|
]
|
|
26
26
|
}
|
|
@@ -31,7 +31,7 @@
|
|
|
31
31
|
"hooks": [
|
|
32
32
|
{
|
|
33
33
|
"type": "command",
|
|
34
|
-
"command": "SHOOTER_USE_LOCAL=true SHOOTER_LOCAL_PORT
|
|
34
|
+
"command": "SHOOTER_USE_LOCAL=true SHOOTER_LOCAL_PORT=${SHOOTER_LOCAL_PORT:-54007} API_KEY=$API_KEY node .claude/hooks/notifier.cjs PostToolUseFailure"
|
|
35
35
|
}
|
|
36
36
|
]
|
|
37
37
|
}
|
|
@@ -42,7 +42,7 @@
|
|
|
42
42
|
"hooks": [
|
|
43
43
|
{
|
|
44
44
|
"type": "command",
|
|
45
|
-
"command": "SHOOTER_USE_LOCAL=true SHOOTER_LOCAL_PORT
|
|
45
|
+
"command": "SHOOTER_USE_LOCAL=true SHOOTER_LOCAL_PORT=${SHOOTER_LOCAL_PORT:-54007} API_KEY=$API_KEY node .claude/hooks/notifier.cjs Stop"
|
|
46
46
|
}
|
|
47
47
|
]
|
|
48
48
|
}
|
|
@@ -53,7 +53,7 @@
|
|
|
53
53
|
"hooks": [
|
|
54
54
|
{
|
|
55
55
|
"type": "command",
|
|
56
|
-
"command": "SHOOTER_USE_LOCAL=true SHOOTER_LOCAL_PORT
|
|
56
|
+
"command": "SHOOTER_USE_LOCAL=true SHOOTER_LOCAL_PORT=${SHOOTER_LOCAL_PORT:-54007} API_KEY=$API_KEY node .claude/hooks/notifier.cjs SessionStart"
|
|
57
57
|
}
|
|
58
58
|
]
|
|
59
59
|
}
|
|
@@ -64,7 +64,7 @@
|
|
|
64
64
|
"hooks": [
|
|
65
65
|
{
|
|
66
66
|
"type": "command",
|
|
67
|
-
"command": "SHOOTER_USE_LOCAL=true SHOOTER_LOCAL_PORT
|
|
67
|
+
"command": "SHOOTER_USE_LOCAL=true SHOOTER_LOCAL_PORT=${SHOOTER_LOCAL_PORT:-54007} API_KEY=$API_KEY node .claude/hooks/notifier.cjs SessionEnd"
|
|
68
68
|
}
|
|
69
69
|
]
|
|
70
70
|
}
|
|
@@ -75,7 +75,7 @@
|
|
|
75
75
|
"hooks": [
|
|
76
76
|
{
|
|
77
77
|
"type": "command",
|
|
78
|
-
"command": "SHOOTER_USE_LOCAL=true SHOOTER_LOCAL_PORT
|
|
78
|
+
"command": "SHOOTER_USE_LOCAL=true SHOOTER_LOCAL_PORT=${SHOOTER_LOCAL_PORT:-54007} API_KEY=$API_KEY node .claude/hooks/notifier.cjs Notification"
|
|
79
79
|
}
|
|
80
80
|
]
|
|
81
81
|
}
|
|
@@ -86,7 +86,7 @@
|
|
|
86
86
|
"hooks": [
|
|
87
87
|
{
|
|
88
88
|
"type": "command",
|
|
89
|
-
"command": "SHOOTER_USE_LOCAL=true SHOOTER_LOCAL_PORT
|
|
89
|
+
"command": "SHOOTER_USE_LOCAL=true SHOOTER_LOCAL_PORT=${SHOOTER_LOCAL_PORT:-54007} API_KEY=$API_KEY node .claude/hooks/notifier.cjs PermissionRequest",
|
|
90
90
|
"timeout": 180
|
|
91
91
|
}
|
|
92
92
|
]
|
|
@@ -98,7 +98,7 @@
|
|
|
98
98
|
"hooks": [
|
|
99
99
|
{
|
|
100
100
|
"type": "command",
|
|
101
|
-
"command": "SHOOTER_USE_LOCAL=true SHOOTER_LOCAL_PORT
|
|
101
|
+
"command": "SHOOTER_USE_LOCAL=true SHOOTER_LOCAL_PORT=${SHOOTER_LOCAL_PORT:-54007} API_KEY=$API_KEY node .claude/hooks/notifier.cjs SubagentStart"
|
|
102
102
|
}
|
|
103
103
|
]
|
|
104
104
|
}
|
|
@@ -109,7 +109,7 @@
|
|
|
109
109
|
"hooks": [
|
|
110
110
|
{
|
|
111
111
|
"type": "command",
|
|
112
|
-
"command": "SHOOTER_USE_LOCAL=true SHOOTER_LOCAL_PORT
|
|
112
|
+
"command": "SHOOTER_USE_LOCAL=true SHOOTER_LOCAL_PORT=${SHOOTER_LOCAL_PORT:-54007} API_KEY=$API_KEY node .claude/hooks/notifier.cjs SubagentStop"
|
|
113
113
|
}
|
|
114
114
|
]
|
|
115
115
|
}
|
|
@@ -120,7 +120,7 @@
|
|
|
120
120
|
"hooks": [
|
|
121
121
|
{
|
|
122
122
|
"type": "command",
|
|
123
|
-
"command": "SHOOTER_USE_LOCAL=true SHOOTER_LOCAL_PORT
|
|
123
|
+
"command": "SHOOTER_USE_LOCAL=true SHOOTER_LOCAL_PORT=${SHOOTER_LOCAL_PORT:-54007} API_KEY=$API_KEY node .claude/hooks/notifier.cjs UserPromptSubmit"
|
|
124
124
|
}
|
|
125
125
|
]
|
|
126
126
|
}
|
|
@@ -131,7 +131,7 @@
|
|
|
131
131
|
"hooks": [
|
|
132
132
|
{
|
|
133
133
|
"type": "command",
|
|
134
|
-
"command": "SHOOTER_USE_LOCAL=true SHOOTER_LOCAL_PORT
|
|
134
|
+
"command": "SHOOTER_USE_LOCAL=true SHOOTER_LOCAL_PORT=${SHOOTER_LOCAL_PORT:-54007} API_KEY=$API_KEY node .claude/hooks/notifier.cjs TeammateIdle"
|
|
135
135
|
}
|
|
136
136
|
]
|
|
137
137
|
}
|
|
@@ -142,7 +142,7 @@
|
|
|
142
142
|
"hooks": [
|
|
143
143
|
{
|
|
144
144
|
"type": "command",
|
|
145
|
-
"command": "SHOOTER_USE_LOCAL=true SHOOTER_LOCAL_PORT
|
|
145
|
+
"command": "SHOOTER_USE_LOCAL=true SHOOTER_LOCAL_PORT=${SHOOTER_LOCAL_PORT:-54007} API_KEY=$API_KEY node .claude/hooks/notifier.cjs TaskCompleted"
|
|
146
146
|
}
|
|
147
147
|
]
|
|
148
148
|
}
|
|
@@ -153,7 +153,7 @@
|
|
|
153
153
|
"hooks": [
|
|
154
154
|
{
|
|
155
155
|
"type": "command",
|
|
156
|
-
"command": "SHOOTER_USE_LOCAL=true SHOOTER_LOCAL_PORT
|
|
156
|
+
"command": "SHOOTER_USE_LOCAL=true SHOOTER_LOCAL_PORT=${SHOOTER_LOCAL_PORT:-54007} API_KEY=$API_KEY node .claude/hooks/notifier.cjs PreCompact"
|
|
157
157
|
}
|
|
158
158
|
]
|
|
159
159
|
}
|
package/README.md
CHANGED
|
@@ -33,27 +33,37 @@ Shooter turns your phone into a remote control for AI coding sessions running on
|
|
|
33
33
|
|
|
34
34
|
## Quick Start
|
|
35
35
|
|
|
36
|
+
**One-command install** (recommended):
|
|
37
|
+
|
|
38
|
+
```bash
|
|
39
|
+
curl -fsSL https://raw.githubusercontent.com/juspay/shooter/release/scripts/install.sh | sh
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
This clones to `~/.shooter/repo`, auto-generates an API key, installs dependencies, builds, offers to install cloudflared for remote access, enables autostart on login, and starts the server.
|
|
43
|
+
|
|
44
|
+
**Or clone and set up manually:**
|
|
45
|
+
|
|
36
46
|
```bash
|
|
37
47
|
git clone https://github.com/juspay/shooter.git
|
|
38
48
|
cd shooter
|
|
39
49
|
pnpm install
|
|
40
50
|
pnpm setup # interactive wizard: generates .env, builds, runs health check
|
|
41
|
-
pnpm start # start the server on http://localhost:
|
|
51
|
+
pnpm start # start the server on http://localhost:54007
|
|
42
52
|
```
|
|
43
53
|
|
|
44
|
-
Open [http://localhost:
|
|
54
|
+
Open [http://localhost:54007](http://localhost:54007) in your browser. Visit `/config` to enter your API key for the web UI.
|
|
45
55
|
|
|
46
56
|
---
|
|
47
57
|
|
|
48
58
|
## All Setup Methods
|
|
49
59
|
|
|
50
|
-
| Method
|
|
51
|
-
|
|
52
|
-
|
|
|
53
|
-
|
|
|
54
|
-
|
|
|
55
|
-
| Docker
|
|
56
|
-
| Manual
|
|
60
|
+
| Method | Command | Notes |
|
|
61
|
+
| ------------------- | ---------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------- |
|
|
62
|
+
| One-command install | `curl -fsSL https://raw.githubusercontent.com/juspay/shooter/release/scripts/install.sh \| sh` | Recommended. Clones to `~/.shooter/repo`, auto-generates API key, builds, installs cloudflared, starts server |
|
|
63
|
+
| Interactive wizard | `pnpm setup` | Walks through env config, builds, and verifies. Pass `--auto` for non-interactive mode. |
|
|
64
|
+
| CLI (npx) | `npx @juspay/shooter setup` | No clone needed -- runs the setup wizard directly from npm |
|
|
65
|
+
| Docker | `docker compose up -d` | See [Docker](#docker) |
|
|
66
|
+
| Manual | See [Manual Setup](#manual-setup) | For advanced users |
|
|
57
67
|
|
|
58
68
|
### Manual Setup
|
|
59
69
|
|
|
@@ -82,7 +92,7 @@ source ~/.zshrc
|
|
|
82
92
|
+----------------------------------------------------------+
|
|
83
93
|
| Dev Machine |
|
|
84
94
|
| |
|
|
85
|
-
| SvelteKit Server (adapter-node, port
|
|
95
|
+
| SvelteKit Server (adapter-node, port 54007) |
|
|
86
96
|
| +-- REST API (/api/terminals, /api/notify, ...) |
|
|
87
97
|
| +-- WebSocket Server (ws, noServer mode) |
|
|
88
98
|
| +-- PTY Manager (node-pty + holder processes) |
|
|
@@ -111,11 +121,11 @@ source ~/.zshrc
|
|
|
111
121
|
|
|
112
122
|
**Three WebSocket channels:**
|
|
113
123
|
|
|
114
|
-
| Channel
|
|
115
|
-
|
|
116
|
-
| Terminal I/O
|
|
117
|
-
| Session stream | `/ws/session/:id`
|
|
118
|
-
| Global events
|
|
124
|
+
| Channel | Path | Purpose |
|
|
125
|
+
| -------------- | ------------------ | ---------------------------------------------------- |
|
|
126
|
+
| Terminal I/O | `/ws/terminal/:id` | Raw PTY byte stream (xterm.js) |
|
|
127
|
+
| Session stream | `/ws/session/:id` | Structured AI conversation updates |
|
|
128
|
+
| Global events | `/ws/events` | Server broadcasts (new sessions, exits, permissions) |
|
|
119
129
|
|
|
120
130
|
---
|
|
121
131
|
|
|
@@ -123,21 +133,21 @@ source ~/.zshrc
|
|
|
123
133
|
|
|
124
134
|
Copy `.env.example` to `.env` and fill in your values. The `pnpm setup` wizard handles this interactively.
|
|
125
135
|
|
|
126
|
-
| Variable
|
|
127
|
-
|
|
128
|
-
| `API_KEY`
|
|
129
|
-
| `PORT`
|
|
130
|
-
| `DEVICE_PLATFORM`
|
|
131
|
-
| `APNS_KEY`
|
|
132
|
-
| `APNS_KEY_ID`
|
|
133
|
-
| `APNS_TEAM_ID`
|
|
134
|
-
| `APNS_BUNDLE_ID`
|
|
135
|
-
| `APNS_PRODUCTION`
|
|
136
|
-
| `DEVICE_TOKEN`
|
|
137
|
-
| `FCM_PROJECT_ID`
|
|
138
|
-
| `FCM_CLIENT_EMAIL`
|
|
139
|
-
| `FCM_PRIVATE_KEY`
|
|
140
|
-
| `ANDROID_DEVICE_TOKEN` | No
|
|
136
|
+
| Variable | Required | Default | Description |
|
|
137
|
+
| ---------------------- | -------- | ------- | ---------------------------------------------------------------- |
|
|
138
|
+
| `API_KEY` | **Yes** | -- | Bearer token for authenticating all API and hook requests |
|
|
139
|
+
| `PORT` | No | `54007` | HTTP server port |
|
|
140
|
+
| `DEVICE_PLATFORM` | No | `ios` | Push notification target: `ios` or `android` |
|
|
141
|
+
| `APNS_KEY` | No | -- | APNs private key (`.p8` file contents, newlines escaped as `\n`) |
|
|
142
|
+
| `APNS_KEY_ID` | No | -- | 10-character APNs key identifier from Apple Developer portal |
|
|
143
|
+
| `APNS_TEAM_ID` | No | -- | 10-character Apple Team ID |
|
|
144
|
+
| `APNS_BUNDLE_ID` | No | -- | iOS app bundle identifier (must match Xcode project) |
|
|
145
|
+
| `APNS_PRODUCTION` | No | `false` | Set `true` for TestFlight / App Store builds |
|
|
146
|
+
| `DEVICE_TOKEN` | No | -- | Target iOS device token (64-character hex) |
|
|
147
|
+
| `FCM_PROJECT_ID` | No | -- | Firebase project ID |
|
|
148
|
+
| `FCM_CLIENT_EMAIL` | No | -- | Firebase service account email |
|
|
149
|
+
| `FCM_PRIVATE_KEY` | No | -- | Firebase service account private key (PEM format) |
|
|
150
|
+
| `ANDROID_DEVICE_TOKEN` | No | -- | Target Android FCM device token |
|
|
141
151
|
|
|
142
152
|
---
|
|
143
153
|
|
|
@@ -225,22 +235,22 @@ Shooter integrates with Claude Code through lifecycle hooks defined in `.claude/
|
|
|
225
235
|
|
|
226
236
|
### Captured Events
|
|
227
237
|
|
|
228
|
-
| Hook
|
|
229
|
-
|
|
230
|
-
| `PreToolUse`
|
|
231
|
-
| `PostToolUse`
|
|
232
|
-
| `PostToolUseFailure` | After a tool fails
|
|
233
|
-
| `PermissionRequest`
|
|
234
|
-
| `SessionStart`
|
|
235
|
-
| `SessionEnd`
|
|
236
|
-
| `Stop`
|
|
237
|
-
| `Notification`
|
|
238
|
-
| `SubagentStart`
|
|
239
|
-
| `SubagentStop`
|
|
240
|
-
| `UserPromptSubmit`
|
|
241
|
-
| `TeammateIdle`
|
|
242
|
-
| `TaskCompleted`
|
|
243
|
-
| `PreCompact`
|
|
238
|
+
| Hook | Description |
|
|
239
|
+
| -------------------- | --------------------------------------------------------------- |
|
|
240
|
+
| `PreToolUse` | Before a tool executes (file edit, bash command, etc.) |
|
|
241
|
+
| `PostToolUse` | After a tool completes successfully |
|
|
242
|
+
| `PostToolUseFailure` | After a tool fails |
|
|
243
|
+
| `PermissionRequest` | Claude Code asks for permission -- **blocks until you respond** |
|
|
244
|
+
| `SessionStart` | A new coding session begins |
|
|
245
|
+
| `SessionEnd` | A coding session ends |
|
|
246
|
+
| `Stop` | Claude Code stops execution |
|
|
247
|
+
| `Notification` | General notification from Claude Code |
|
|
248
|
+
| `SubagentStart` | A subagent is spawned |
|
|
249
|
+
| `SubagentStop` | A subagent completes |
|
|
250
|
+
| `UserPromptSubmit` | User submits a prompt |
|
|
251
|
+
| `TeammateIdle` | A teammate agent becomes idle |
|
|
252
|
+
| `TaskCompleted` | A task finishes |
|
|
253
|
+
| `PreCompact` | Before context compaction |
|
|
244
254
|
|
|
245
255
|
### Permission Flow
|
|
246
256
|
|
|
@@ -254,13 +264,13 @@ The `PermissionRequest` hook has a 180-second timeout in `.claude/settings.json`
|
|
|
254
264
|
|
|
255
265
|
### Hook Environment Variables
|
|
256
266
|
|
|
257
|
-
| Variable
|
|
258
|
-
|
|
259
|
-
| `SHOOTER_USE_LOCAL`
|
|
260
|
-
| `SHOOTER_LOCAL_PORT`
|
|
261
|
-
| `SHOOTER_API_URL`
|
|
262
|
-
| `SHOOTER_PERMISSION_TIMEOUT` | `120`
|
|
263
|
-
| `API_KEY`
|
|
267
|
+
| Variable | Default | Description |
|
|
268
|
+
| ---------------------------- | ------- | ----------------------------------------------------------- |
|
|
269
|
+
| `SHOOTER_USE_LOCAL` | -- | Set `true` to connect to local server instead of remote URL |
|
|
270
|
+
| `SHOOTER_LOCAL_PORT` | `54007` | Local server port when using `SHOOTER_USE_LOCAL` |
|
|
271
|
+
| `SHOOTER_API_URL` | -- | Remote server URL (when not using local) |
|
|
272
|
+
| `SHOOTER_PERMISSION_TIMEOUT` | `120` | Seconds to wait for a permission response |
|
|
273
|
+
| `API_KEY` | -- | Bearer token (must match the server's `API_KEY`) |
|
|
264
274
|
|
|
265
275
|
---
|
|
266
276
|
|
|
@@ -282,7 +292,7 @@ docker build -t shooter .
|
|
|
282
292
|
docker run -d \
|
|
283
293
|
--name shooter \
|
|
284
294
|
--env-file .env \
|
|
285
|
-
-p
|
|
295
|
+
-p 54007:54007 \
|
|
286
296
|
-v shooter-data:/root/.shooter \
|
|
287
297
|
--restart unless-stopped \
|
|
288
298
|
shooter
|
|
@@ -290,6 +300,8 @@ docker run -d \
|
|
|
290
300
|
|
|
291
301
|
The multi-stage Dockerfile uses `node:20-slim` and includes build tools for `node-pty` and `better-sqlite3` native addons. SQLite data is persisted in the `shooter-data` volume. The `.env` file is injected at runtime and never baked into the image.
|
|
292
302
|
|
|
303
|
+
A separate `Dockerfile.test` is provided for verifying the fresh-user install experience in an isolated container.
|
|
304
|
+
|
|
293
305
|
### docker-compose.yml
|
|
294
306
|
|
|
295
307
|
```yaml
|
|
@@ -297,7 +309,7 @@ services:
|
|
|
297
309
|
shooter:
|
|
298
310
|
build: .
|
|
299
311
|
ports:
|
|
300
|
-
-
|
|
312
|
+
- '54007:54007'
|
|
301
313
|
env_file:
|
|
302
314
|
- .env
|
|
303
315
|
volumes:
|
|
@@ -314,25 +326,25 @@ volumes:
|
|
|
314
326
|
|
|
315
327
|
All endpoints require the `Authorization: Bearer <API_KEY>` header.
|
|
316
328
|
|
|
317
|
-
| Method
|
|
318
|
-
|
|
319
|
-
| `GET`
|
|
320
|
-
| `GET`
|
|
321
|
-
| `POST`
|
|
322
|
-
| `GET`
|
|
323
|
-
| `DELETE` | `/api/terminals/:id`
|
|
324
|
-
| `POST`
|
|
325
|
-
| `POST`
|
|
326
|
-
| `GET`
|
|
327
|
-
| `POST`
|
|
328
|
-
| `GET`
|
|
329
|
-
| `POST`
|
|
330
|
-
| `GET`
|
|
331
|
-
| `GET`
|
|
332
|
-
| `POST`
|
|
333
|
-
| `GET`
|
|
334
|
-
| `POST`
|
|
335
|
-
| `GET`
|
|
329
|
+
| Method | Path | Description |
|
|
330
|
+
| -------- | --------------------------- | ---------------------------------------------------- |
|
|
331
|
+
| `GET` | `/api/health` | Health check with server status |
|
|
332
|
+
| `GET` | `/api/terminals` | List all active and recently exited terminals |
|
|
333
|
+
| `POST` | `/api/terminals` | Create a new terminal session |
|
|
334
|
+
| `GET` | `/api/terminals/:id` | Get details for a specific terminal |
|
|
335
|
+
| `DELETE` | `/api/terminals/:id` | Kill and remove a terminal session |
|
|
336
|
+
| `POST` | `/api/terminals/:id/resize` | Resize a terminal (cols, rows) |
|
|
337
|
+
| `POST` | `/api/ws-ticket` | Generate a short-lived WebSocket auth ticket |
|
|
338
|
+
| `GET` | `/api/ws-status` | Get connected WebSocket client count |
|
|
339
|
+
| `POST` | `/api/notify` | Send a push notification via APNs or FCM |
|
|
340
|
+
| `GET` | `/api/notify` | Check notification status and history |
|
|
341
|
+
| `POST` | `/api/response` | Submit a permission allow/deny decision |
|
|
342
|
+
| `GET` | `/api/response` | Poll for a pending permission decision |
|
|
343
|
+
| `GET` | `/api/sessions` | List sessions across all projects |
|
|
344
|
+
| `POST` | `/api/webhook` | Receive external webhook events |
|
|
345
|
+
| `GET` | `/api/qr-config` | Generate QR code for mobile app pairing |
|
|
346
|
+
| `POST` | `/api/device-token` | Register a device token (iOS or Android) |
|
|
347
|
+
| `GET` | `/api/debug` | Debug information (APNs config, device token status) |
|
|
336
348
|
|
|
337
349
|
### WebSocket Authentication
|
|
338
350
|
|
|
@@ -341,7 +353,7 @@ WebSocket connections use ticket-based auth. First call `POST /api/ws-ticket` wi
|
|
|
341
353
|
### Example: Create Terminal
|
|
342
354
|
|
|
343
355
|
```bash
|
|
344
|
-
curl -X POST http://localhost:
|
|
356
|
+
curl -X POST http://localhost:54007/api/terminals \
|
|
345
357
|
-H "Authorization: Bearer $API_KEY" \
|
|
346
358
|
-H "Content-Type: application/json" \
|
|
347
359
|
-d '{"command": "claude", "cwd": "/Users/me/project", "cols": 80, "rows": 24}'
|
|
@@ -380,6 +392,24 @@ pnpm format:check # Check formatting without writing
|
|
|
380
392
|
|
|
381
393
|
**Note:** `pnpm dev` runs the Vite dev server, which does not include the WebSocket server or PTY manager. For full functionality (terminal sessions, live streaming), use `pnpm build && pnpm start`.
|
|
382
394
|
|
|
395
|
+
### CLI Commands
|
|
396
|
+
|
|
397
|
+
The `shooter` command (via `bin/shooter.cjs` or the global `shooter` symlink) supports:
|
|
398
|
+
|
|
399
|
+
| Command | Description |
|
|
400
|
+
| -------------------- | ------------------------------------------------------------------ |
|
|
401
|
+
| `shooter start` | Start the server (default if no command given) |
|
|
402
|
+
| `shooter stop` | Stop the running server gracefully (SIGTERM, then SIGKILL after 5s)|
|
|
403
|
+
| `shooter status` | Show PID, URL, autostart state, log path |
|
|
404
|
+
| `shooter autostart on` | Enable autostart on login (LaunchAgent on macOS, systemd on Linux) |
|
|
405
|
+
| `shooter autostart off` | Disable autostart and remove the service definition |
|
|
406
|
+
| `shooter logs` | Tail server logs (log file on macOS, journalctl on Linux) |
|
|
407
|
+
| `shooter setup` | Run the interactive setup wizard; pass `--auto` for non-interactive|
|
|
408
|
+
| `shooter version` | Print version number |
|
|
409
|
+
| `shooter help` | Show all available commands |
|
|
410
|
+
|
|
411
|
+
Process state is tracked via a PID file at `~/.shooter/shooter.pid`. Logs are written to `~/.shooter/logs/shooter.log` when running via autostart.
|
|
412
|
+
|
|
383
413
|
### Type System
|
|
384
414
|
|
|
385
415
|
Types are auto-generated from YAML specifications in `specs/types/` using [type-crafter](https://github.com/nicktaf/type-crafter). Never edit files in `src/generated/types/` directly -- edit the YAML specs and run `pnpm run gen:types`.
|
|
@@ -390,18 +420,19 @@ Types are auto-generated from YAML specifications in `specs/types/` using [type-
|
|
|
390
420
|
|
|
391
421
|
```
|
|
392
422
|
shooter/
|
|
393
|
-
server.ts # HTTP + WebSocket server entry point
|
|
423
|
+
server.ts # HTTP + WebSocket server entry point (build guard check)
|
|
394
424
|
package.json # Dependencies and scripts (pnpm only)
|
|
395
425
|
Dockerfile # Multi-stage Docker build
|
|
426
|
+
Dockerfile.test # Test image for fresh-user install verification
|
|
396
427
|
docker-compose.yml # Docker Compose config
|
|
397
428
|
.env.example # Environment variable template
|
|
398
429
|
svelte.config.js # SvelteKit config (adapter-node)
|
|
399
430
|
vite.config.ts # Vite config (node-pty external)
|
|
400
431
|
bin/
|
|
401
|
-
shooter.cjs # CLI entry point (
|
|
432
|
+
shooter.cjs # CLI entry point (start|stop|status|autostart|logs|setup|help)
|
|
402
433
|
scripts/
|
|
403
|
-
setup.cjs # Interactive setup wizard
|
|
404
|
-
install.sh # One-command
|
|
434
|
+
setup.cjs # Interactive setup wizard (--auto for non-interactive)
|
|
435
|
+
install.sh # One-command installer (full auto setup + cloudflared)
|
|
405
436
|
.claude/
|
|
406
437
|
hooks/notifier.cjs # Unified hook notifier (Node.js)
|
|
407
438
|
settings.json # Hook configuration (13 event types)
|
|
@@ -458,8 +489,9 @@ shooter/
|
|
|
458
489
|
|
|
459
490
|
- Verify Node.js 20+ is installed: `node --version`
|
|
460
491
|
- Ensure pnpm is used (npm and yarn are blocked): `pnpm --version`
|
|
461
|
-
- Check that `pnpm build` completed without errors before running `pnpm start`
|
|
462
|
-
- Confirm `.env` exists and `API_KEY` is set
|
|
492
|
+
- Check that `pnpm build` completed without errors before running `pnpm start` -- `server.ts` has a build guard that exits with a clear error if `build/handler.js` is missing
|
|
493
|
+
- Confirm `.env` exists and `API_KEY` is set (the server also checks `~/.shooter/.env` as a fallback)
|
|
494
|
+
- On Linux, ensure build tools are installed: `python3`, `make`, `g++` (needed for native modules)
|
|
463
495
|
|
|
464
496
|
### WebSocket connections fail
|
|
465
497
|
|
|
@@ -479,7 +511,7 @@ shooter/
|
|
|
479
511
|
|
|
480
512
|
- `API_KEY` must be exported in your shell environment, not just in `.env`: `export API_KEY="..."`
|
|
481
513
|
- Verify the hooks are configured in `.claude/settings.json`
|
|
482
|
-
- Test connectivity: `curl -H "Authorization: Bearer $API_KEY" http://localhost:
|
|
514
|
+
- Test connectivity: `curl -H "Authorization: Bearer $API_KEY" http://localhost:54007/api/health`
|
|
483
515
|
|
|
484
516
|
### Terminal sessions lost after restart
|
|
485
517
|
|
|
@@ -494,8 +526,8 @@ shooter/
|
|
|
494
526
|
|
|
495
527
|
### Port already in use
|
|
496
528
|
|
|
497
|
-
- Default port is
|
|
498
|
-
- Check what is using the port: `lsof -i :
|
|
529
|
+
- Default port is 54007. Set `PORT=<number>` in `.env` to use a different port.
|
|
530
|
+
- Check what is using the port: `lsof -i :54007`
|
|
499
531
|
|
|
500
532
|
---
|
|
501
533
|
|