@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.
Files changed (433) hide show
  1. package/.claude/hooks/notifier.cjs +117 -33
  2. package/.claude/settings.json +14 -14
  3. package/README.md +116 -84
  4. package/bin/shooter.cjs +471 -102
  5. package/build/client/_app/immutable/assets/{0.CM9Hl6d-.css → 0.DC5pAwP3.css} +1 -1
  6. package/build/client/_app/immutable/assets/0.DC5pAwP3.css.br +0 -0
  7. package/build/client/_app/immutable/assets/{0.CM9Hl6d-.css.gz → 0.DC5pAwP3.css.gz} +0 -0
  8. package/build/client/_app/immutable/assets/2.CAShZ7lQ.css.gz +0 -0
  9. package/build/client/_app/immutable/assets/3.BoXp0JoS.css +1 -0
  10. package/build/client/_app/immutable/assets/3.BoXp0JoS.css.br +0 -0
  11. package/build/client/_app/immutable/assets/3.BoXp0JoS.css.gz +0 -0
  12. package/build/client/_app/immutable/assets/4.cJuCkJKZ.css.gz +0 -0
  13. package/build/client/_app/immutable/assets/5.DRjApZQW.css.gz +0 -0
  14. package/build/client/_app/immutable/assets/6.eZGZN-BF.css +1 -0
  15. package/build/client/_app/immutable/assets/6.eZGZN-BF.css.br +0 -0
  16. package/build/client/_app/immutable/assets/6.eZGZN-BF.css.gz +0 -0
  17. package/build/client/_app/immutable/assets/{7.BCJ1IuMx.css → 7.PyEFVv_s.css} +1 -1
  18. package/build/client/_app/immutable/assets/7.PyEFVv_s.css.br +0 -0
  19. package/build/client/_app/immutable/assets/7.PyEFVv_s.css.gz +0 -0
  20. package/build/client/_app/immutable/assets/ChatView.CsdBAOKx.css.gz +0 -0
  21. package/build/client/_app/immutable/assets/Phone.FQEfwCX2.css +1 -0
  22. package/build/client/_app/immutable/assets/Phone.FQEfwCX2.css.br +0 -0
  23. package/build/client/_app/immutable/assets/Phone.FQEfwCX2.css.gz +0 -0
  24. package/build/client/_app/immutable/assets/markdown.Dc-OSJWY.css +1 -0
  25. package/build/client/_app/immutable/assets/markdown.Dc-OSJWY.css.br +0 -0
  26. package/build/client/_app/immutable/assets/markdown.Dc-OSJWY.css.gz +0 -0
  27. package/build/client/_app/immutable/assets/xterm.DFuMZ0ql.css.gz +0 -0
  28. package/build/client/_app/immutable/chunks/{Cjwk_cGO.js → 50RPd5u3.js} +1 -1
  29. package/build/client/_app/immutable/chunks/50RPd5u3.js.br +0 -0
  30. package/build/client/_app/immutable/chunks/50RPd5u3.js.gz +0 -0
  31. package/build/client/_app/immutable/chunks/BDC7XD4o.js +1 -0
  32. package/build/client/_app/immutable/chunks/BDC7XD4o.js.br +0 -0
  33. package/build/client/_app/immutable/chunks/BDC7XD4o.js.gz +0 -0
  34. package/build/client/_app/immutable/chunks/BTGVxaYV.js.gz +0 -0
  35. package/build/client/_app/immutable/chunks/BeONA6_G.js +2 -0
  36. package/build/client/_app/immutable/chunks/BeONA6_G.js.br +0 -0
  37. package/build/client/_app/immutable/chunks/BeONA6_G.js.gz +0 -0
  38. package/build/client/_app/immutable/chunks/BlxrFPDK.js.gz +0 -0
  39. package/build/client/_app/immutable/chunks/BygiiMA0.js +1 -0
  40. package/build/client/_app/immutable/chunks/BygiiMA0.js.br +0 -0
  41. package/build/client/_app/immutable/chunks/BygiiMA0.js.gz +0 -0
  42. package/build/client/_app/immutable/chunks/CGLrx-H5.js.gz +0 -0
  43. package/build/client/_app/immutable/chunks/CHvUpVYv.js +1 -0
  44. package/build/client/_app/immutable/chunks/CHvUpVYv.js.br +0 -0
  45. package/build/client/_app/immutable/chunks/CHvUpVYv.js.gz +0 -0
  46. package/build/client/_app/immutable/chunks/CbqC9BW7.js +1 -0
  47. package/build/client/_app/immutable/chunks/CbqC9BW7.js.br +2 -0
  48. package/build/client/_app/immutable/chunks/CbqC9BW7.js.gz +0 -0
  49. package/build/client/_app/immutable/chunks/CdL99jkG.js +1 -0
  50. package/build/client/_app/immutable/chunks/CdL99jkG.js.br +0 -0
  51. package/build/client/_app/immutable/chunks/CdL99jkG.js.gz +0 -0
  52. package/build/client/_app/immutable/chunks/ClK4wZbC.js +61 -0
  53. package/build/client/_app/immutable/chunks/ClK4wZbC.js.br +0 -0
  54. package/build/client/_app/immutable/chunks/ClK4wZbC.js.gz +0 -0
  55. package/build/client/_app/immutable/chunks/CojFyTPp.js +1 -0
  56. package/build/client/_app/immutable/chunks/CojFyTPp.js.br +0 -0
  57. package/build/client/_app/immutable/chunks/CojFyTPp.js.gz +0 -0
  58. package/build/client/_app/immutable/chunks/DLu6yJIZ.js.gz +0 -0
  59. package/build/client/_app/immutable/chunks/DREFAyhX.js +60 -0
  60. package/build/client/_app/immutable/chunks/DREFAyhX.js.br +0 -0
  61. package/build/client/_app/immutable/chunks/DREFAyhX.js.gz +0 -0
  62. package/build/client/_app/immutable/chunks/DSU1n5N_.js +1 -0
  63. package/build/client/_app/immutable/chunks/DSU1n5N_.js.br +0 -0
  64. package/build/client/_app/immutable/chunks/DSU1n5N_.js.gz +0 -0
  65. package/build/client/_app/immutable/chunks/K_aHH2KN.js +1 -0
  66. package/build/client/_app/immutable/chunks/K_aHH2KN.js.br +0 -0
  67. package/build/client/_app/immutable/chunks/K_aHH2KN.js.gz +0 -0
  68. package/build/client/_app/immutable/chunks/Ona8oofC.js +1 -0
  69. package/build/client/_app/immutable/chunks/Ona8oofC.js.br +0 -0
  70. package/build/client/_app/immutable/chunks/Ona8oofC.js.gz +0 -0
  71. package/build/client/_app/immutable/chunks/PPVm8Dsz.js.gz +0 -0
  72. package/build/client/_app/immutable/chunks/tjbnEgXP.js +1 -0
  73. package/build/client/_app/immutable/chunks/tjbnEgXP.js.br +0 -0
  74. package/build/client/_app/immutable/chunks/tjbnEgXP.js.gz +0 -0
  75. package/build/client/_app/immutable/entry/app.anqwe7ZL.js +2 -0
  76. package/build/client/_app/immutable/entry/app.anqwe7ZL.js.br +0 -0
  77. package/build/client/_app/immutable/entry/app.anqwe7ZL.js.gz +0 -0
  78. package/build/client/_app/immutable/entry/start.BV2VRv6h.js +1 -0
  79. package/build/client/_app/immutable/entry/start.BV2VRv6h.js.br +2 -0
  80. package/build/client/_app/immutable/entry/start.BV2VRv6h.js.gz +0 -0
  81. package/build/client/_app/immutable/nodes/0.D0i5MqcI.js +1 -0
  82. package/build/client/_app/immutable/nodes/0.D0i5MqcI.js.br +0 -0
  83. package/build/client/_app/immutable/nodes/0.D0i5MqcI.js.gz +0 -0
  84. package/build/client/_app/immutable/nodes/1.DN5n5c6F.js +1 -0
  85. package/build/client/_app/immutable/nodes/1.DN5n5c6F.js.br +0 -0
  86. package/build/client/_app/immutable/nodes/1.DN5n5c6F.js.gz +0 -0
  87. package/build/client/_app/immutable/nodes/2.BTjkNKZJ.js +1 -0
  88. package/build/client/_app/immutable/nodes/2.BTjkNKZJ.js.br +0 -0
  89. package/build/client/_app/immutable/nodes/2.BTjkNKZJ.js.gz +0 -0
  90. package/build/client/_app/immutable/nodes/3.CEkigHDv.js +3 -0
  91. package/build/client/_app/immutable/nodes/3.CEkigHDv.js.br +0 -0
  92. package/build/client/_app/immutable/nodes/3.CEkigHDv.js.gz +0 -0
  93. package/build/client/_app/immutable/nodes/4.B-8Zsc9k.js +1 -0
  94. package/build/client/_app/immutable/nodes/4.B-8Zsc9k.js.br +0 -0
  95. package/build/client/_app/immutable/nodes/4.B-8Zsc9k.js.gz +0 -0
  96. package/build/client/_app/immutable/nodes/5.shitbtHc.js +1 -0
  97. package/build/client/_app/immutable/nodes/5.shitbtHc.js.br +0 -0
  98. package/build/client/_app/immutable/nodes/5.shitbtHc.js.gz +0 -0
  99. package/build/client/_app/immutable/nodes/6.CB8Q6eH8.js +2 -0
  100. package/build/client/_app/immutable/nodes/6.CB8Q6eH8.js.br +0 -0
  101. package/build/client/_app/immutable/nodes/6.CB8Q6eH8.js.gz +0 -0
  102. package/build/client/_app/immutable/nodes/7.D0CrR6pl.js +2 -0
  103. package/build/client/_app/immutable/nodes/7.D0CrR6pl.js.br +0 -0
  104. package/build/client/_app/immutable/nodes/7.D0CrR6pl.js.gz +0 -0
  105. package/build/client/_app/version.json +1 -1
  106. package/build/client/_app/version.json.br +0 -0
  107. package/build/client/_app/version.json.gz +0 -0
  108. package/build/client/favicon.svg.gz +0 -0
  109. package/build/pty-holder.cjs +37 -8
  110. package/build/server/chunks/0-Cs1dzfRz.js +9 -0
  111. package/build/server/chunks/{0-q2IUp76Y.js.map → 0-Cs1dzfRz.js.map} +1 -1
  112. package/build/server/chunks/1-BCSX7oED.js +9 -0
  113. package/build/server/chunks/{1-CU50G5wZ.js.map → 1-BCSX7oED.js.map} +1 -1
  114. package/build/server/chunks/2-6gkeO8b4.js +9 -0
  115. package/build/server/chunks/2-6gkeO8b4.js.map +1 -0
  116. package/build/server/chunks/3-DH9J9Vsc.js +9 -0
  117. package/build/server/chunks/3-DH9J9Vsc.js.map +1 -0
  118. package/build/server/chunks/4-Rzy5TYjl.js +9 -0
  119. package/build/server/chunks/4-Rzy5TYjl.js.map +1 -0
  120. package/build/server/chunks/5-D0wB7nfE.js +9 -0
  121. package/build/server/chunks/5-D0wB7nfE.js.map +1 -0
  122. package/build/server/chunks/6-DR2ABDPq.js +9 -0
  123. package/build/server/chunks/6-DR2ABDPq.js.map +1 -0
  124. package/build/server/chunks/7-D-oQJsia.js +9 -0
  125. package/build/server/chunks/7-D-oQJsia.js.map +1 -0
  126. package/build/server/chunks/Button-C7D5W6wV.js +80 -0
  127. package/build/server/chunks/Button-C7D5W6wV.js.map +1 -0
  128. package/build/server/chunks/EmptyState-Ci4pSpmY.js +20 -0
  129. package/build/server/chunks/EmptyState-Ci4pSpmY.js.map +1 -0
  130. package/build/server/chunks/Icon-DyrkHVnV.js +36 -0
  131. package/build/server/chunks/Icon-DyrkHVnV.js.map +1 -0
  132. package/build/server/chunks/Shimmer-BITK6wrm.js +10 -0
  133. package/build/server/chunks/Shimmer-BITK6wrm.js.map +1 -0
  134. package/build/server/chunks/_layout.svelte-CO4f8UD7.js +76 -0
  135. package/build/server/chunks/_layout.svelte-CO4f8UD7.js.map +1 -0
  136. package/build/server/chunks/_page.svelte-3Cc3NMAP.js +81 -0
  137. package/build/server/chunks/_page.svelte-3Cc3NMAP.js.map +1 -0
  138. package/build/server/chunks/_page.svelte-C0p3HsIW.js +46 -0
  139. package/build/server/chunks/_page.svelte-C0p3HsIW.js.map +1 -0
  140. package/build/server/chunks/_page.svelte-C6bns9aQ.js +41 -0
  141. package/build/server/chunks/_page.svelte-C6bns9aQ.js.map +1 -0
  142. package/build/server/chunks/_page.svelte-CFCONiDK.js +97 -0
  143. package/build/server/chunks/_page.svelte-CFCONiDK.js.map +1 -0
  144. package/build/server/chunks/_page.svelte-DskND_G9.js +550 -0
  145. package/build/server/chunks/_page.svelte-DskND_G9.js.map +1 -0
  146. package/build/server/chunks/_page.svelte-rTrWmhOp.js +651 -0
  147. package/build/server/chunks/_page.svelte-rTrWmhOp.js.map +1 -0
  148. package/build/server/chunks/{_server.ts-CbDRDIoP.js → _server.ts-BStnNIcq.js} +9 -11
  149. package/build/server/chunks/_server.ts-BStnNIcq.js.map +1 -0
  150. package/build/server/chunks/{_server.ts-C29xzfaw.js → _server.ts-C8slOHB0.js} +9 -10
  151. package/build/server/chunks/_server.ts-C8slOHB0.js.map +1 -0
  152. package/build/server/chunks/{_server.ts-CPa6DgIt.js → _server.ts-COu0vNpd.js} +6 -6
  153. package/build/server/chunks/_server.ts-COu0vNpd.js.map +1 -0
  154. package/build/server/chunks/{_server.ts-DRVbgm6k.js → _server.ts-CS5H5klP.js} +10 -17
  155. package/build/server/chunks/_server.ts-CS5H5klP.js.map +1 -0
  156. package/build/server/chunks/{_server.ts-D4MNi4cD.js → _server.ts-Cf84YIaW.js} +3 -3
  157. package/build/server/chunks/{_server.ts-D4MNi4cD.js.map → _server.ts-Cf84YIaW.js.map} +1 -1
  158. package/build/server/chunks/{_server.ts-BL2FGb5Z.js → _server.ts-Ch-6iOHp.js} +99 -53
  159. package/build/server/chunks/_server.ts-Ch-6iOHp.js.map +1 -0
  160. package/build/server/chunks/{_server.ts-DfajWaqh.js → _server.ts-DV8zTCF9.js} +7 -9
  161. package/build/server/chunks/_server.ts-DV8zTCF9.js.map +1 -0
  162. package/build/server/chunks/{_server.ts-ColfDHW8.js → _server.ts-DYvb9ijZ.js} +21 -10
  163. package/build/server/chunks/_server.ts-DYvb9ijZ.js.map +1 -0
  164. package/build/server/chunks/_server.ts-DhTrdlWH.js +62 -0
  165. package/build/server/chunks/_server.ts-DhTrdlWH.js.map +1 -0
  166. package/build/server/chunks/{_server.ts-Cv_OrRuL.js → _server.ts-DpEVfp8W.js} +165 -8
  167. package/build/server/chunks/_server.ts-DpEVfp8W.js.map +1 -0
  168. package/build/server/chunks/{_server.ts-y9-WYDMa.js → _server.ts-WhTJBEJy.js} +5 -4
  169. package/build/server/chunks/{_server.ts-y9-WYDMa.js.map → _server.ts-WhTJBEJy.js.map} +1 -1
  170. package/build/server/chunks/{_server.ts-BjOJsoy4.js → _server.ts-XzT2UHM1.js} +6 -5
  171. package/build/server/chunks/_server.ts-XzT2UHM1.js.map +1 -0
  172. package/build/server/chunks/{_server.ts-BgdjBZco.js → _server.ts-tSpgyl1D.js} +7 -5
  173. package/build/server/chunks/_server.ts-tSpgyl1D.js.map +1 -0
  174. package/build/server/chunks/{_server.ts-BihKSdj_.js → _server.ts-uHUi-4cd.js} +7 -8
  175. package/build/server/chunks/_server.ts-uHUi-4cd.js.map +1 -0
  176. package/build/server/chunks/{auth-CEgFis71.js → auth-DeCdZ83n.js} +2 -2
  177. package/build/server/chunks/{auth-CEgFis71.js.map → auth-DeCdZ83n.js.map} +1 -1
  178. package/build/server/chunks/client-BYT9c0ig.js +7 -0
  179. package/build/server/chunks/client-BYT9c0ig.js.map +1 -0
  180. package/build/server/chunks/client2-BjxIYuno.js +25 -0
  181. package/build/server/chunks/client2-BjxIYuno.js.map +1 -0
  182. package/build/server/chunks/error-DDXB3duW.js +12 -0
  183. package/build/server/chunks/error-DDXB3duW.js.map +1 -0
  184. package/build/server/chunks/error.svelte-BG_yE-Wt.js +27 -0
  185. package/build/server/chunks/error.svelte-BG_yE-Wt.js.map +1 -0
  186. package/build/server/chunks/{exports-CJ0Q5XmL.js → index-Cnl871UW.js} +1111 -1634
  187. package/build/server/chunks/index-Cnl871UW.js.map +1 -0
  188. package/build/server/chunks/index-server-CUC9Jt7r.js +9 -0
  189. package/build/server/chunks/index-server-CUC9Jt7r.js.map +1 -0
  190. package/build/server/chunks/index2-HA3VTH7y.js +58 -0
  191. package/build/server/chunks/index2-HA3VTH7y.js.map +1 -0
  192. package/build/server/chunks/{library-apns-BHxLmuIx.js → library-apns-BqJbvSKh.js} +4 -4
  193. package/build/server/chunks/library-apns-BqJbvSKh.js.map +1 -0
  194. package/build/server/chunks/markdown-W_mTBct0.js +8 -0
  195. package/build/server/chunks/markdown-W_mTBct0.js.map +1 -0
  196. package/build/server/chunks/{pty-manager-C0FhBiVq.js → pty-manager-DR0Wt2Ac.js} +146 -319
  197. package/build/server/chunks/pty-manager-DR0Wt2Ac.js.map +1 -0
  198. package/build/server/chunks/root-DhswcH6o.js +1171 -0
  199. package/build/server/chunks/root-DhswcH6o.js.map +1 -0
  200. package/build/server/chunks/{shared-server-BDY8jh20.js → shared-server-sSGG17Df.js} +2 -3
  201. package/build/server/chunks/{shared-server-BDY8jh20.js.map → shared-server-sSGG17Df.js.map} +1 -1
  202. package/build/server/chunks/state.svelte-2Lellg7t.js +11 -0
  203. package/build/server/chunks/state.svelte-2Lellg7t.js.map +1 -0
  204. package/build/server/index.js +1085 -2242
  205. package/build/server/index.js.map +1 -1
  206. package/build/server/manifest.js +23 -23
  207. package/build/server/manifest.js.map +1 -1
  208. package/package.json +32 -9
  209. package/scripts/fix-generated-types.sh +37 -0
  210. package/scripts/homebrew/shooter.rb +51 -0
  211. package/scripts/install.sh +348 -186
  212. package/scripts/setup.cjs +139 -43
  213. package/server.ts +111 -71
  214. package/src/app.css +12 -3
  215. package/src/app.d.ts +13 -20
  216. package/src/app.html +0 -2
  217. package/src/generated/types/API.ts +280 -0
  218. package/src/generated/types/APN.ts +186 -203
  219. package/src/generated/types/CLI.ts +18 -25
  220. package/src/generated/types/Client.ts +589 -0
  221. package/src/generated/types/Config.ts +53 -0
  222. package/src/generated/types/Holder.ts +638 -0
  223. package/src/generated/types/JWT.ts +39 -50
  224. package/src/generated/types/Notification.ts +426 -0
  225. package/src/generated/types/OpenCode.ts +356 -0
  226. package/src/generated/types/Sessions.ts +570 -0
  227. package/src/generated/types/Terminal.ts +2184 -2071
  228. package/src/generated/types/WsProtocol.ts +2004 -0
  229. package/src/generated/types/index.ts +9 -3
  230. package/src/lib/env.ts +29 -0
  231. package/src/lib/modules/client/common/config-guard.ts +37 -5
  232. package/src/lib/modules/client/common/error.ts +10 -0
  233. package/src/lib/modules/client/common/index.ts +6 -5
  234. package/src/lib/modules/client/common/native-bridge.ts +28 -20
  235. package/src/lib/modules/client/terminal/ChatView.svelte +46 -23
  236. package/src/lib/modules/client/terminal/CommandPalette.svelte +3 -2
  237. package/src/lib/modules/client/terminal/ConnectionStatus.svelte +6 -1
  238. package/src/lib/modules/client/terminal/LaunchSheet.svelte +147 -84
  239. package/src/lib/modules/client/terminal/QuickKeys.svelte +3 -1
  240. package/src/lib/modules/client/terminal/ShortcutsHelp.svelte +2 -5
  241. package/src/lib/modules/client/terminal/keyboard-shortcuts.ts +27 -24
  242. package/src/lib/modules/client/terminal/xterm-wrapper.ts +70 -44
  243. package/src/lib/modules/server/apn/library-apns.ts +3 -2
  244. package/src/lib/modules/server/apn/notification-history.ts +2 -13
  245. package/src/lib/modules/server/apn/notification-sessions.ts +3 -13
  246. package/src/lib/modules/server/apn/pending-requests.ts +3 -8
  247. package/src/lib/modules/server/apn/types.ts +5 -4
  248. package/src/lib/modules/server/cli/index.ts +3 -2
  249. package/src/lib/modules/server/fcm/fcm-service.ts +8 -6
  250. package/src/lib/modules/server/sessions/jsonl-parser.ts +3 -3
  251. package/src/lib/modules/server/sessions/jsonl-reader.ts +60 -15
  252. package/src/lib/modules/server/sessions/types.ts +11 -22
  253. package/src/lib/modules/server/terminal/holder-client.ts +272 -248
  254. package/src/lib/modules/server/terminal/opencode-watcher.ts +555 -553
  255. package/src/lib/modules/server/terminal/pty-holder.cjs +37 -8
  256. package/src/lib/modules/server/terminal/pty-manager.ts +141 -111
  257. package/src/lib/modules/server/terminal/session-watcher.ts +6 -4
  258. package/src/lib/modules/server/terminal/terminal-store.ts +131 -128
  259. package/src/lib/modules/server/utils/error.ts +9 -0
  260. package/src/lib/modules/server/ws/events-handler.ts +12 -6
  261. package/src/lib/modules/server/ws/keepalive.ts +86 -69
  262. package/src/lib/modules/server/ws/server.ts +43 -37
  263. package/src/lib/modules/server/ws/session-handler.ts +52 -45
  264. package/src/lib/modules/server/ws/terminal-handler.ts +29 -17
  265. package/src/lib/modules/server/ws/ticket-store.ts +29 -26
  266. package/src/lib/types/config.ts +1 -6
  267. package/src/routes/+layout.svelte +66 -31
  268. package/src/routes/+page.svelte +8 -15
  269. package/src/routes/api/debug/+server.ts +3 -1
  270. package/src/routes/api/device-token/+server.ts +60 -60
  271. package/src/routes/api/health/+server.ts +69 -73
  272. package/src/routes/api/notify/+server.ts +115 -68
  273. package/src/routes/api/qr-config/+server.ts +30 -32
  274. package/src/routes/api/response/+server.ts +9 -4
  275. package/src/routes/api/sessions/+server.ts +3 -1
  276. package/src/routes/api/terminals/+server.ts +14 -15
  277. package/src/routes/api/terminals/[id]/+server.ts +13 -7
  278. package/src/routes/api/terminals/[id]/paste-image/+server.ts +54 -52
  279. package/src/routes/api/terminals/[id]/resize/+server.ts +6 -3
  280. package/src/routes/api/webhook/+server.ts +8 -10
  281. package/src/routes/api/ws-status/+server.ts +7 -5
  282. package/src/routes/api/ws-ticket/+server.ts +42 -41
  283. package/src/routes/config/+page.svelte +129 -76
  284. package/src/routes/project/+page.svelte +7 -28
  285. package/src/routes/session/[id]/+page.svelte +70 -52
  286. package/src/routes/terminals/+page.svelte +45 -43
  287. package/src/routes/terminals/[id]/+page.svelte +198 -91
  288. package/build/client/_app/immutable/assets/0.CM9Hl6d-.css.br +0 -0
  289. package/build/client/_app/immutable/assets/3.C0uFg0IS.css +0 -1
  290. package/build/client/_app/immutable/assets/3.C0uFg0IS.css.br +0 -0
  291. package/build/client/_app/immutable/assets/3.C0uFg0IS.css.gz +0 -0
  292. package/build/client/_app/immutable/assets/6.AraZrY8I.css +0 -1
  293. package/build/client/_app/immutable/assets/6.AraZrY8I.css.br +0 -0
  294. package/build/client/_app/immutable/assets/6.AraZrY8I.css.gz +0 -0
  295. package/build/client/_app/immutable/assets/7.BCJ1IuMx.css.br +0 -0
  296. package/build/client/_app/immutable/assets/7.BCJ1IuMx.css.gz +0 -0
  297. package/build/client/_app/immutable/assets/markdown.B0b5w2tq.css +0 -1
  298. package/build/client/_app/immutable/assets/markdown.B0b5w2tq.css.br +0 -0
  299. package/build/client/_app/immutable/assets/markdown.B0b5w2tq.css.gz +0 -0
  300. package/build/client/_app/immutable/chunks/BNJphC1q.js +0 -56
  301. package/build/client/_app/immutable/chunks/BNJphC1q.js.br +0 -0
  302. package/build/client/_app/immutable/chunks/BNJphC1q.js.gz +0 -0
  303. package/build/client/_app/immutable/chunks/Bvk7mfPM.js +0 -1
  304. package/build/client/_app/immutable/chunks/Bvk7mfPM.js.br +0 -0
  305. package/build/client/_app/immutable/chunks/Bvk7mfPM.js.gz +0 -0
  306. package/build/client/_app/immutable/chunks/CAokzuPQ.js +0 -1
  307. package/build/client/_app/immutable/chunks/CAokzuPQ.js.br +0 -0
  308. package/build/client/_app/immutable/chunks/CAokzuPQ.js.gz +0 -0
  309. package/build/client/_app/immutable/chunks/CgCpWzEA.js +0 -1
  310. package/build/client/_app/immutable/chunks/CgCpWzEA.js.br +0 -0
  311. package/build/client/_app/immutable/chunks/CgCpWzEA.js.gz +0 -0
  312. package/build/client/_app/immutable/chunks/Cjwk_cGO.js.br +0 -0
  313. package/build/client/_app/immutable/chunks/Cjwk_cGO.js.gz +0 -0
  314. package/build/client/_app/immutable/chunks/CtQ8EED1.js +0 -11
  315. package/build/client/_app/immutable/chunks/CtQ8EED1.js.br +0 -0
  316. package/build/client/_app/immutable/chunks/CtQ8EED1.js.gz +0 -0
  317. package/build/client/_app/immutable/chunks/DERQCisl.js +0 -1
  318. package/build/client/_app/immutable/chunks/DERQCisl.js.br +0 -0
  319. package/build/client/_app/immutable/chunks/DERQCisl.js.gz +0 -0
  320. package/build/client/_app/immutable/chunks/DKrg8TQs.js +0 -1
  321. package/build/client/_app/immutable/chunks/DKrg8TQs.js.br +0 -0
  322. package/build/client/_app/immutable/chunks/DKrg8TQs.js.gz +0 -0
  323. package/build/client/_app/immutable/chunks/Dkkpz_4D.js +0 -126
  324. package/build/client/_app/immutable/chunks/Dkkpz_4D.js.br +0 -0
  325. package/build/client/_app/immutable/chunks/Dkkpz_4D.js.gz +0 -0
  326. package/build/client/_app/immutable/chunks/DoczjQhA.js +0 -1
  327. package/build/client/_app/immutable/chunks/DoczjQhA.js.br +0 -0
  328. package/build/client/_app/immutable/chunks/DoczjQhA.js.gz +0 -0
  329. package/build/client/_app/immutable/chunks/RpcNruLP.js +0 -2
  330. package/build/client/_app/immutable/chunks/RpcNruLP.js.br +0 -0
  331. package/build/client/_app/immutable/chunks/RpcNruLP.js.gz +0 -0
  332. package/build/client/_app/immutable/chunks/a-St0Zwo.js +0 -1
  333. package/build/client/_app/immutable/chunks/a-St0Zwo.js.br +0 -0
  334. package/build/client/_app/immutable/chunks/a-St0Zwo.js.gz +0 -0
  335. package/build/client/_app/immutable/chunks/bo70OQUZ.js +0 -1
  336. package/build/client/_app/immutable/chunks/bo70OQUZ.js.br +0 -0
  337. package/build/client/_app/immutable/chunks/bo70OQUZ.js.gz +0 -0
  338. package/build/client/_app/immutable/entry/app.QvGgdvTI.js +0 -2
  339. package/build/client/_app/immutable/entry/app.QvGgdvTI.js.br +0 -0
  340. package/build/client/_app/immutable/entry/app.QvGgdvTI.js.gz +0 -0
  341. package/build/client/_app/immutable/entry/start.BntDNRMC.js +0 -1
  342. package/build/client/_app/immutable/entry/start.BntDNRMC.js.br +0 -0
  343. package/build/client/_app/immutable/entry/start.BntDNRMC.js.gz +0 -0
  344. package/build/client/_app/immutable/nodes/0.CzkdvJ7j.js +0 -1
  345. package/build/client/_app/immutable/nodes/0.CzkdvJ7j.js.br +0 -0
  346. package/build/client/_app/immutable/nodes/0.CzkdvJ7j.js.gz +0 -0
  347. package/build/client/_app/immutable/nodes/1.MG1QhfrI.js +0 -1
  348. package/build/client/_app/immutable/nodes/1.MG1QhfrI.js.br +0 -0
  349. package/build/client/_app/immutable/nodes/1.MG1QhfrI.js.gz +0 -0
  350. package/build/client/_app/immutable/nodes/2.B4MlOSh6.js +0 -1
  351. package/build/client/_app/immutable/nodes/2.B4MlOSh6.js.br +0 -0
  352. package/build/client/_app/immutable/nodes/2.B4MlOSh6.js.gz +0 -0
  353. package/build/client/_app/immutable/nodes/3.DIwYkjDn.js +0 -3
  354. package/build/client/_app/immutable/nodes/3.DIwYkjDn.js.br +0 -0
  355. package/build/client/_app/immutable/nodes/3.DIwYkjDn.js.gz +0 -0
  356. package/build/client/_app/immutable/nodes/4.D-cIe70D.js +0 -1
  357. package/build/client/_app/immutable/nodes/4.D-cIe70D.js.br +0 -0
  358. package/build/client/_app/immutable/nodes/4.D-cIe70D.js.gz +0 -0
  359. package/build/client/_app/immutable/nodes/5.D7zPRe3L.js +0 -1
  360. package/build/client/_app/immutable/nodes/5.D7zPRe3L.js.br +0 -0
  361. package/build/client/_app/immutable/nodes/5.D7zPRe3L.js.gz +0 -0
  362. package/build/client/_app/immutable/nodes/6.BB7QE48r.js +0 -2
  363. package/build/client/_app/immutable/nodes/6.BB7QE48r.js.br +0 -0
  364. package/build/client/_app/immutable/nodes/6.BB7QE48r.js.gz +0 -0
  365. package/build/client/_app/immutable/nodes/7.D8mqsrZG.js +0 -2
  366. package/build/client/_app/immutable/nodes/7.D8mqsrZG.js.br +0 -0
  367. package/build/client/_app/immutable/nodes/7.D8mqsrZG.js.gz +0 -0
  368. package/build/client/manifest.webmanifest +0 -1
  369. package/build/client/registerSW.js +0 -1
  370. package/build/client/registerSW.js.br +0 -0
  371. package/build/client/registerSW.js.gz +0 -0
  372. package/build/client/sw.js +0 -222
  373. package/build/client/sw.js.br +0 -0
  374. package/build/client/sw.js.gz +0 -0
  375. package/build/client/workbox-5119daf5.js +0 -3395
  376. package/build/client/workbox-5119daf5.js.br +0 -0
  377. package/build/client/workbox-5119daf5.js.gz +0 -0
  378. package/build/server/chunks/0-q2IUp76Y.js +0 -9
  379. package/build/server/chunks/1-CU50G5wZ.js +0 -9
  380. package/build/server/chunks/2-D01t9s8T.js +0 -9
  381. package/build/server/chunks/2-D01t9s8T.js.map +0 -1
  382. package/build/server/chunks/3-5PUQ04wC.js +0 -9
  383. package/build/server/chunks/3-5PUQ04wC.js.map +0 -1
  384. package/build/server/chunks/4-e7gywnSG.js +0 -9
  385. package/build/server/chunks/4-e7gywnSG.js.map +0 -1
  386. package/build/server/chunks/5-CA1SA6KZ.js +0 -9
  387. package/build/server/chunks/5-CA1SA6KZ.js.map +0 -1
  388. package/build/server/chunks/6-71H221sV.js +0 -9
  389. package/build/server/chunks/6-71H221sV.js.map +0 -1
  390. package/build/server/chunks/7-Bo-vmdyz.js +0 -9
  391. package/build/server/chunks/7-Bo-vmdyz.js.map +0 -1
  392. package/build/server/chunks/_layout.svelte-SFHOxs74.js +0 -132
  393. package/build/server/chunks/_layout.svelte-SFHOxs74.js.map +0 -1
  394. package/build/server/chunks/_page.svelte-B4w-2wD-.js +0 -120
  395. package/build/server/chunks/_page.svelte-B4w-2wD-.js.map +0 -1
  396. package/build/server/chunks/_page.svelte-B_qAXjkh.js +0 -213
  397. package/build/server/chunks/_page.svelte-B_qAXjkh.js.map +0 -1
  398. package/build/server/chunks/_page.svelte-CsF1_TRG.js +0 -50
  399. package/build/server/chunks/_page.svelte-CsF1_TRG.js.map +0 -1
  400. package/build/server/chunks/_page.svelte-DJC6U-P0.js +0 -68
  401. package/build/server/chunks/_page.svelte-DJC6U-P0.js.map +0 -1
  402. package/build/server/chunks/_page.svelte-DQ6HBtsz.js +0 -407
  403. package/build/server/chunks/_page.svelte-DQ6HBtsz.js.map +0 -1
  404. package/build/server/chunks/_page.svelte-LbhhjP21.js +0 -148
  405. package/build/server/chunks/_page.svelte-LbhhjP21.js.map +0 -1
  406. package/build/server/chunks/_server.ts-BL2FGb5Z.js.map +0 -1
  407. package/build/server/chunks/_server.ts-BgdjBZco.js.map +0 -1
  408. package/build/server/chunks/_server.ts-BihKSdj_.js.map +0 -1
  409. package/build/server/chunks/_server.ts-BjOJsoy4.js.map +0 -1
  410. package/build/server/chunks/_server.ts-C29xzfaw.js.map +0 -1
  411. package/build/server/chunks/_server.ts-CPa6DgIt.js.map +0 -1
  412. package/build/server/chunks/_server.ts-CbDRDIoP.js.map +0 -1
  413. package/build/server/chunks/_server.ts-Cl1OEWL4.js +0 -54
  414. package/build/server/chunks/_server.ts-Cl1OEWL4.js.map +0 -1
  415. package/build/server/chunks/_server.ts-ColfDHW8.js.map +0 -1
  416. package/build/server/chunks/_server.ts-Cv_OrRuL.js.map +0 -1
  417. package/build/server/chunks/_server.ts-DRVbgm6k.js.map +0 -1
  418. package/build/server/chunks/_server.ts-DfajWaqh.js.map +0 -1
  419. package/build/server/chunks/client-CxCatAKr.js +0 -255
  420. package/build/server/chunks/client-CxCatAKr.js.map +0 -1
  421. package/build/server/chunks/error.svelte-BqdwMWdK.js +0 -26
  422. package/build/server/chunks/error.svelte-BqdwMWdK.js.map +0 -1
  423. package/build/server/chunks/exports-CJ0Q5XmL.js.map +0 -1
  424. package/build/server/chunks/index2-DAxIoAO-.js +0 -36
  425. package/build/server/chunks/index2-DAxIoAO-.js.map +0 -1
  426. package/build/server/chunks/jsonl-parser-dmZU_Hyu.js +0 -137
  427. package/build/server/chunks/jsonl-parser-dmZU_Hyu.js.map +0 -1
  428. package/build/server/chunks/library-apns-BHxLmuIx.js.map +0 -1
  429. package/build/server/chunks/markdown-Bxrl3cCF.js +0 -1241
  430. package/build/server/chunks/markdown-Bxrl3cCF.js.map +0 -1
  431. package/build/server/chunks/pty-manager-C0FhBiVq.js.map +0 -1
  432. package/build/server/chunks/stores-D0HorpgL.js +0 -36
  433. package/build/server/chunks/stores-D0HorpgL.js.map +0 -1
@@ -1,6 +1,12 @@
1
+ export * from './JWT';
1
2
  export * from './APN';
2
- export * from './Apn';
3
3
  export * from './CLI';
4
- export * from './Cli';
5
- export * from './JWT';
6
4
  export * from './Terminal';
5
+ export * from './Sessions';
6
+ export * from './API';
7
+ export * from './WsProtocol';
8
+ export * from './Holder';
9
+ export * from './OpenCode';
10
+ export * from './Notification';
11
+ export * from './Client';
12
+ export * from './Config';
package/src/lib/env.ts ADDED
@@ -0,0 +1,29 @@
1
+ // Side-effect module: loads .env before any other imports.
2
+ // Must be imported first in server.ts.
3
+ //
4
+ // Resolution order:
5
+ // 1. $SHOOTER_HOME/.env (if SHOOTER_HOME is set and file exists)
6
+ // 2. .env in cwd (dotenv default)
7
+ // 3. ~/.shooter/.env (final fallback — setup.cjs writes here)
8
+ import { config } from 'dotenv';
9
+ import { existsSync } from 'fs';
10
+ import { homedir } from 'os';
11
+ import { join } from 'path';
12
+
13
+ const shooterHome = process.env.SHOOTER_HOME || '';
14
+ const envPath = shooterHome ? join(shooterHome, '.env') : undefined;
15
+
16
+ if (envPath && existsSync(envPath)) {
17
+ // 1. SHOOTER_HOME/.env
18
+ config({ path: envPath });
19
+ } else {
20
+ // 2. .env in cwd (dotenv default — only populates vars not already set)
21
+ config();
22
+
23
+ // 3. ~/.shooter/.env as final fallback
24
+ const fallbackPath = join(homedir(), '.shooter', '.env');
25
+ if (existsSync(fallbackPath)) {
26
+ // override: false ensures cwd .env values take precedence
27
+ config({ override: false, path: fallbackPath });
28
+ }
29
+ }
@@ -1,10 +1,11 @@
1
1
  /**
2
2
  * Type guard for ShooterConfig objects stored in localStorage.
3
3
  *
4
- * The stricter variant (used on the config page) validates that apiKey
5
- * and deviceToken are strings. The simpler variant only checks key
6
- * presence. This implementation uses the stricter check so all
7
- * consumers benefit from the extra safety.
4
+ * Validates that the required apiKey field is a non-empty string.
5
+ * All other fields (deviceToken, serverUrl, lastUpdated) are nullable
6
+ * in the generated ShooterConfig type, so any parsed object with a
7
+ * valid apiKey is treated as a full ShooterConfig (missing nullable
8
+ * fields default to null at runtime).
8
9
  */
9
10
 
10
11
  import type { ShooterConfig } from '$lib/types/config';
@@ -14,5 +15,36 @@ export function isShooterConfig(value: unknown): value is ShooterConfig {
14
15
  return false;
15
16
  }
16
17
  const obj = value as Record<string, unknown>;
17
- return typeof obj.apiKey === 'string' && typeof obj.deviceToken === 'string';
18
+ if (typeof obj.apiKey !== 'string' || obj.apiKey.length === 0) {
19
+ return false;
20
+ }
21
+ // Validate nullable fields are string | null | undefined (reject numbers, booleans, etc.)
22
+ if (
23
+ obj.deviceToken !== undefined &&
24
+ obj.deviceToken !== null &&
25
+ typeof obj.deviceToken !== 'string'
26
+ ) {
27
+ return false;
28
+ }
29
+ if (obj.serverUrl !== undefined && obj.serverUrl !== null && typeof obj.serverUrl !== 'string') {
30
+ return false;
31
+ }
32
+ if (
33
+ obj.lastUpdated !== undefined &&
34
+ obj.lastUpdated !== null &&
35
+ typeof obj.lastUpdated !== 'string'
36
+ ) {
37
+ return false;
38
+ }
39
+ // Normalize nullable fields so the value satisfies ShooterConfig at runtime
40
+ if (obj.deviceToken === undefined) {
41
+ obj.deviceToken = null;
42
+ }
43
+ if (obj.serverUrl === undefined) {
44
+ obj.serverUrl = null;
45
+ }
46
+ if (obj.lastUpdated === undefined) {
47
+ obj.lastUpdated = null;
48
+ }
49
+ return true;
18
50
  }
@@ -0,0 +1,10 @@
1
+ /** Extract a human-readable message from an unknown thrown value. */
2
+ export function toErrorMessage(err: unknown): string {
3
+ if (err instanceof Error) {
4
+ return err.message;
5
+ }
6
+ if (typeof err === 'string') {
7
+ return err;
8
+ }
9
+ return String(err);
10
+ }
@@ -1,12 +1,13 @@
1
- export { default as Card } from './Card.svelte';
2
- export { default as EmptyState } from './EmptyState.svelte';
3
- export { default as Icon } from './Icon.svelte';
4
- export { default as StatusBadge } from './StatusBadge.svelte';
5
-
6
1
  // Shared client utilities
7
2
  export { getCached, setCache } from './cache';
3
+ export { default as Card } from './Card.svelte';
8
4
  export { isShooterConfig } from './config-guard';
5
+ export { default as EmptyState } from './EmptyState.svelte';
6
+ export { toErrorMessage } from './error';
7
+
8
+ export { default as Icon } from './Icon.svelte';
9
9
  export { renderMarkdown } from './markdown';
10
10
  export { hasScanner, isNativeBridge, scanQR } from './native-bridge';
11
+ export { default as StatusBadge } from './StatusBadge.svelte';
11
12
  export { formatRelativeTime } from './time';
12
13
  export { getToolDescription } from './tool-title';
@@ -8,34 +8,23 @@
8
8
  * resolving scanner/picker promises using its own callback registry.
9
9
  */
10
10
 
11
+ /** True when the native bridge exposes a QR scanner */
12
+ export function hasScanner(): boolean {
13
+ return getScanFn() !== null;
14
+ }
15
+
11
16
  /** True when the page is running inside a native WebView with a bridge */
12
17
  export function isNativeBridge(): boolean {
13
- if (typeof window === 'undefined') return false;
18
+ if (typeof window === 'undefined') {
19
+ return false;
20
+ }
14
21
  // iOS injects window.ShooterBridge, Android injects window.ShooterNativeBridge
15
22
  return (
16
23
  (typeof window.ShooterBridge === 'object' && window.ShooterBridge !== null) ||
17
- (typeof (window as any).ShooterNativeBridge === 'object' && (window as any).ShooterNativeBridge !== null)
24
+ (typeof window.ShooterNativeBridge === 'object' && window.ShooterNativeBridge !== null)
18
25
  );
19
26
  }
20
27
 
21
- /** Get the scanner.scan function from whichever bridge exists */
22
- function getScanFn(): (() => Promise<string>) | null {
23
- if (typeof window === 'undefined') return null;
24
- // Check iOS bridge first, then Android
25
- if (typeof window.ShooterBridge?.scanner?.scan === 'function') {
26
- return () => window.ShooterBridge!.scanner!.scan();
27
- }
28
- if (typeof (window as any).ShooterNativeBridge?.scanner?.scan === 'function') {
29
- return () => (window as any).ShooterNativeBridge.scanner.scan();
30
- }
31
- return null;
32
- }
33
-
34
- /** True when the native bridge exposes a QR scanner */
35
- export function hasScanner(): boolean {
36
- return getScanFn() !== null;
37
- }
38
-
39
28
  /**
40
29
  * Invoke the native QR scanner.
41
30
  * Returns the scanned string on success, throws on cancel/error.
@@ -48,3 +37,22 @@ export async function scanQR(): Promise<string> {
48
37
  }
49
38
  return scan();
50
39
  }
40
+
41
+ /** Get the scanner.scan function from whichever bridge exists */
42
+ function getScanFn(): (() => Promise<string>) | null {
43
+ if (typeof window === 'undefined') {
44
+ return null;
45
+ }
46
+ // Check iOS bridge first, then Android.
47
+ // Capture the scanner object (not the bare function) to preserve `this` binding
48
+ // when the native side implements scan() as a method on the scanner object.
49
+ const iosScanner = window.ShooterBridge?.scanner;
50
+ if (iosScanner && typeof iosScanner.scan === 'function') {
51
+ return () => iosScanner.scan();
52
+ }
53
+ const androidScanner = window.ShooterNativeBridge?.scanner;
54
+ if (androidScanner && typeof androidScanner.scan === 'function') {
55
+ return () => androidScanner.scan();
56
+ }
57
+ return null;
58
+ }
@@ -5,11 +5,8 @@
5
5
  ToolUsePart,
6
6
  } from '$lib/modules/server/sessions/types';
7
7
 
8
+ import { getToolDescription, renderMarkdown } from '$lib/modules/client/common';
8
9
  import { Accordion, Avatar, Button, Input, Pill } from '@juspay/svelte-ui-components';
9
- import {
10
- getToolDescription,
11
- renderMarkdown,
12
- } from '$lib/modules/client/common';
13
10
  import { tick } from 'svelte';
14
11
  import { SvelteSet } from 'svelte/reactivity';
15
12
 
@@ -48,13 +45,17 @@
48
45
  });
49
46
 
50
47
  async function scrollToBottom(): Promise<void> {
51
- if (!shouldAutoScroll || !chatContainerEl) { return; }
48
+ if (!shouldAutoScroll || !chatContainerEl) {
49
+ return;
50
+ }
52
51
  await tick();
53
52
  chatContainerEl.scrollTop = chatContainerEl.scrollHeight;
54
53
  }
55
54
 
56
55
  function handleScroll(): void {
57
- if (!chatContainerEl) { return; }
56
+ if (!chatContainerEl) {
57
+ return;
58
+ }
58
59
  const { clientHeight, scrollHeight, scrollTop } = chatContainerEl;
59
60
  shouldAutoScroll = scrollHeight - scrollTop - clientHeight < 100;
60
61
  }
@@ -62,7 +63,9 @@
62
63
  // --- Input handling ---
63
64
  function handleSend(): void {
64
65
  const text = inputText.trim();
65
- if (!text) { return; }
66
+ if (!text) {
67
+ return;
68
+ }
66
69
  inputText = '';
67
70
  onSendInput?.(text);
68
71
  }
@@ -109,9 +112,7 @@
109
112
  <span class="chatview-title">Session</span>
110
113
  </div>
111
114
  <div class="chatview-header-right">
112
- <span
113
- class="connection-status {connectionState}"
114
- >
115
+ <span class="connection-status {connectionState}">
115
116
  <span class="connection-status-dot"></span>
116
117
  {connectionState === 'connected'
117
118
  ? 'Connected'
@@ -120,18 +121,20 @@
120
121
  : 'Disconnected'}
121
122
  </span>
122
123
  {#if !sessionEnded && onCancel}
123
- <Button classes="btn-danger btn-sm" onclick={() => { onCancel(); }} text="Cancel" />
124
+ <Button
125
+ classes="btn-danger btn-sm"
126
+ onclick={() => {
127
+ onCancel();
128
+ }}
129
+ text="Cancel"
130
+ />
124
131
  {/if}
125
132
  </div>
126
133
  </div>
127
134
  {/if}
128
135
 
129
136
  <!-- Chat Container (scrollable) -->
130
- <div
131
- class="chat-container chatview-scroll"
132
- bind:this={chatContainerEl}
133
- onscroll={handleScroll}
134
- >
137
+ <div class="chat-container chatview-scroll" bind:this={chatContainerEl} onscroll={handleScroll}>
135
138
  {#if messages.length === 0}
136
139
  <div class="chatview-empty">
137
140
  <p class="chatview-empty-text">Waiting for session messages...</p>
@@ -144,6 +147,7 @@
144
147
  {#each message.parts as part, partIdx (partIdx)}
145
148
  {#if part.type === 'text'}
146
149
  <div class="chat-bubble chat-bubble-user">
150
+ <!-- eslint-disable-next-line svelte/no-at-html-tags -- sanitized markdown -->
147
151
  {@html renderMarkdown(part.content)}
148
152
  </div>
149
153
  {/if}
@@ -159,6 +163,7 @@
159
163
  {#each message.parts as part, partIdx (partIdx)}
160
164
  {#if part.type === 'text'}
161
165
  <div class="chat-bubble chat-bubble-assistant">
166
+ <!-- eslint-disable-next-line svelte/no-at-html-tags -- sanitized markdown -->
162
167
  {@html renderMarkdown(part.content)}
163
168
  </div>
164
169
  {:else if isToolUsePart(part)}
@@ -167,9 +172,14 @@
167
172
  <div class="chat-tool-card">
168
173
  <div
169
174
  class="chat-tool-header"
170
- onclick={() => { toggleTool(toolId); }}
175
+ onclick={() => {
176
+ toggleTool(toolId);
177
+ }}
171
178
  onkeydown={(e) => {
172
- if (e.key === 'Enter' || e.key === ' ') { toggleTool(toolId); }
179
+ if (e.key === 'Enter' || e.key === ' ') {
180
+ e.preventDefault();
181
+ toggleTool(toolId);
182
+ }
173
183
  }}
174
184
  role="button"
175
185
  tabindex="0"
@@ -190,9 +200,14 @@
190
200
  <div class="chat-thinking">
191
201
  <div
192
202
  class="chat-thinking-header"
193
- onclick={() => { toggleTool(thinkId); }}
203
+ onclick={() => {
204
+ toggleTool(thinkId);
205
+ }}
194
206
  onkeydown={(e) => {
195
- if (e.key === 'Enter' || e.key === ' ') { toggleTool(thinkId); }
207
+ if (e.key === 'Enter' || e.key === ' ') {
208
+ e.preventDefault();
209
+ toggleTool(thinkId);
210
+ }
196
211
  }}
197
212
  role="button"
198
213
  tabindex="0"
@@ -201,6 +216,7 @@
201
216
  </div>
202
217
  <Accordion expand={isThinkExpanded}>
203
218
  {#if isThinkExpanded}
219
+ <!-- eslint-disable-next-line svelte/no-at-html-tags -- sanitized markdown -->
204
220
  <div class="chat-thinking-body">{@html renderMarkdown(part.content)}</div>
205
221
  {/if}
206
222
  </Accordion>
@@ -219,9 +235,14 @@
219
235
  <div class="chat-tool-card">
220
236
  <div
221
237
  class="chat-tool-header"
222
- onclick={() => { toggleTool(resultId); }}
238
+ onclick={() => {
239
+ toggleTool(resultId);
240
+ }}
223
241
  onkeydown={(e) => {
224
- if (e.key === 'Enter' || e.key === ' ') { toggleTool(resultId); }
242
+ if (e.key === 'Enter' || e.key === ' ') {
243
+ e.preventDefault();
244
+ toggleTool(resultId);
245
+ }
225
246
  }}
226
247
  role="button"
227
248
  tabindex="0"
@@ -249,6 +270,7 @@
249
270
  <!-- System text messages (e.g. error messages displayed inline) -->
250
271
  <div class="chat-message chat-message-system">
251
272
  <div class="chat-bubble chat-bubble-system">
273
+ <!-- eslint-disable-next-line svelte/no-at-html-tags -- sanitized markdown -->
252
274
  {@html renderMarkdown(part.content)}
253
275
  </div>
254
276
  </div>
@@ -273,7 +295,8 @@
273
295
  <Input
274
296
  bind:value={inputText}
275
297
  dataType="text"
276
- placeholder={sessionEnded ? 'Session ended' : 'Send a message...'}
298
+ useTextArea={true}
299
+ placeholder={sessionEnded ? 'Session ended' : 'Send a message... (Shift+Enter for new line)'}
277
300
  disable={sessionEnded || connectionState !== 'connected'}
278
301
  onKeyDown={handleKeydown}
279
302
  classes="chat-input-field"
@@ -9,10 +9,11 @@
9
9
  interface Props {
10
10
  commands: Command[];
11
11
  onClose: () => void;
12
- open: boolean;
12
+ open?: boolean;
13
13
  }
14
14
 
15
- let { commands, onClose, open = $bindable() }: Props = $props();
15
+ // eslint-disable-next-line prefer-const -- open is mutated via bind:open from parent
16
+ let { commands, onClose, open = $bindable(false) }: Props = $props();
16
17
 
17
18
  const items = $derived(
18
19
  commands.map((cmd, i) => ({
@@ -17,7 +17,12 @@
17
17
  );
18
18
  </script>
19
19
 
20
- <div class="connection-status" class:reconnecting={status === 'reconnecting'} class:disconnected={status === 'disconnected'} class:connected={status === 'connected'}>
20
+ <div
21
+ class="connection-status"
22
+ class:reconnecting={status === 'reconnecting'}
23
+ class:disconnected={status === 'disconnected'}
24
+ class:connected={status === 'connected'}
25
+ >
21
26
  <span class="status-dot {status}"></span>
22
27
  <span class="status-label">{label}</span>
23
28
  {#if status === 'disconnected' && onretry}