@juspay/shooter 1.16.0 → 1.18.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 (175) hide show
  1. package/.claude/hooks/codex-hooks.example.json +75 -0
  2. package/.claude/hooks/notifier.cjs +158 -8
  3. package/build/client/_app/immutable/assets/{0.DEfoFaGR.css → 0.NV8k8wxG.css} +1 -1
  4. package/build/client/_app/immutable/assets/0.NV8k8wxG.css.br +0 -0
  5. package/build/client/_app/immutable/assets/0.NV8k8wxG.css.gz +0 -0
  6. package/build/client/_app/immutable/chunks/8lO1IL7u.js +1 -0
  7. package/build/client/_app/immutable/chunks/8lO1IL7u.js.br +0 -0
  8. package/build/client/_app/immutable/chunks/8lO1IL7u.js.gz +0 -0
  9. package/build/client/_app/immutable/chunks/B9WQy_3X.js +1 -0
  10. package/build/client/_app/immutable/chunks/B9WQy_3X.js.br +0 -0
  11. package/build/client/_app/immutable/chunks/B9WQy_3X.js.gz +0 -0
  12. package/build/client/_app/immutable/chunks/BdtLzPpO.js +1 -0
  13. package/build/client/_app/immutable/chunks/BdtLzPpO.js.br +0 -0
  14. package/build/client/_app/immutable/chunks/BdtLzPpO.js.gz +0 -0
  15. package/build/client/_app/immutable/chunks/{DlS3abGJ.js → DJvX78LW.js} +1 -1
  16. package/build/client/_app/immutable/chunks/DJvX78LW.js.br +0 -0
  17. package/build/client/_app/immutable/chunks/DJvX78LW.js.gz +0 -0
  18. package/build/client/_app/immutable/chunks/nWG9RHyB.js +3 -0
  19. package/build/client/_app/immutable/chunks/nWG9RHyB.js.br +0 -0
  20. package/build/client/_app/immutable/chunks/nWG9RHyB.js.gz +0 -0
  21. package/build/client/_app/immutable/entry/{app.CSJG7N9H.js → app.f46Ko1hu.js} +2 -2
  22. package/build/client/_app/immutable/entry/app.f46Ko1hu.js.br +0 -0
  23. package/build/client/_app/immutable/entry/app.f46Ko1hu.js.gz +0 -0
  24. package/build/client/_app/immutable/entry/start.BVDjNnXt.js +1 -0
  25. package/build/client/_app/immutable/entry/start.BVDjNnXt.js.br +2 -0
  26. package/build/client/_app/immutable/entry/start.BVDjNnXt.js.gz +0 -0
  27. package/build/client/_app/immutable/nodes/{0.qOL7xtFn.js → 0.D_9EwVmq.js} +1 -1
  28. package/build/client/_app/immutable/nodes/0.D_9EwVmq.js.br +0 -0
  29. package/build/client/_app/immutable/nodes/0.D_9EwVmq.js.gz +0 -0
  30. package/build/client/_app/immutable/nodes/{1.Di708Ago.js → 1.C4eFlqSB.js} +1 -1
  31. package/build/client/_app/immutable/nodes/1.C4eFlqSB.js.br +0 -0
  32. package/build/client/_app/immutable/nodes/1.C4eFlqSB.js.gz +0 -0
  33. package/build/client/_app/immutable/nodes/{2.DSM1znqa.js → 2.CdC092Za.js} +1 -1
  34. package/build/client/_app/immutable/nodes/2.CdC092Za.js.br +0 -0
  35. package/build/client/_app/immutable/nodes/2.CdC092Za.js.gz +0 -0
  36. package/build/client/_app/immutable/nodes/{3.BPa5fh75.js → 3.Dhf4ZWW0.js} +1 -1
  37. package/build/client/_app/immutable/nodes/3.Dhf4ZWW0.js.br +0 -0
  38. package/build/client/_app/immutable/nodes/3.Dhf4ZWW0.js.gz +0 -0
  39. package/build/client/_app/immutable/nodes/6.B3SEB_li.js +1 -0
  40. package/build/client/_app/immutable/nodes/6.B3SEB_li.js.br +0 -0
  41. package/build/client/_app/immutable/nodes/6.B3SEB_li.js.gz +0 -0
  42. package/build/client/_app/immutable/nodes/{7.B7UJd8GQ.js → 7.DV8cJ1lX.js} +3 -3
  43. package/build/client/_app/immutable/nodes/7.DV8cJ1lX.js.br +0 -0
  44. package/build/client/_app/immutable/nodes/7.DV8cJ1lX.js.gz +0 -0
  45. package/build/client/_app/immutable/nodes/8.Bs362gyb.js +2 -0
  46. package/build/client/_app/immutable/nodes/8.Bs362gyb.js.br +0 -0
  47. package/build/client/_app/immutable/nodes/8.Bs362gyb.js.gz +0 -0
  48. package/build/client/_app/immutable/nodes/9.Cf7_3uqT.js +2 -0
  49. package/build/client/_app/immutable/nodes/9.Cf7_3uqT.js.br +0 -0
  50. package/build/client/_app/immutable/nodes/9.Cf7_3uqT.js.gz +0 -0
  51. package/build/client/_app/version.json +1 -1
  52. package/build/client/_app/version.json.br +0 -0
  53. package/build/client/_app/version.json.gz +0 -0
  54. package/build/server/chunks/{0-D8uPamNd.js → 0-Cd7jY0a7.js} +3 -3
  55. package/build/server/chunks/{0-D8uPamNd.js.map → 0-Cd7jY0a7.js.map} +1 -1
  56. package/build/server/chunks/{1-DhtioHbs.js → 1-C4BOGoJY.js} +2 -2
  57. package/build/server/chunks/{1-DhtioHbs.js.map → 1-C4BOGoJY.js.map} +1 -1
  58. package/build/server/chunks/{2-Cgh7ZFgE.js → 2-Ba0mNwJ6.js} +2 -2
  59. package/build/server/chunks/{2-Cgh7ZFgE.js.map → 2-Ba0mNwJ6.js.map} +1 -1
  60. package/build/server/chunks/{3-I6hnjssH.js → 3-Pg8t1uJU.js} +2 -2
  61. package/build/server/chunks/{3-I6hnjssH.js.map → 3-Pg8t1uJU.js.map} +1 -1
  62. package/build/server/chunks/{6-bPDbH1_W.js → 6-D8xbnTSo.js} +2 -2
  63. package/build/server/chunks/6-D8xbnTSo.js.map +1 -0
  64. package/build/server/chunks/{7-CpBrOkxQ.js → 7-CkVK06S0.js} +2 -2
  65. package/build/server/chunks/7-CkVK06S0.js.map +1 -0
  66. package/build/server/chunks/{8-BRGAVfze.js → 8-C8qVhrds.js} +2 -2
  67. package/build/server/chunks/8-C8qVhrds.js.map +1 -0
  68. package/build/server/chunks/{9-C6xuAb_Y.js → 9-fL5zqN0T.js} +2 -2
  69. package/build/server/chunks/9-fL5zqN0T.js.map +1 -0
  70. package/build/server/chunks/{_server.ts-BrRZXr-8.js → _server.ts-BA_uWcPw.js} +9 -9
  71. package/build/server/chunks/_server.ts-BA_uWcPw.js.map +1 -0
  72. package/build/server/chunks/{_server.ts-C6xbNz6d.js → _server.ts-Bu3s5hfv.js} +3 -3
  73. package/build/server/chunks/{_server.ts-C6xbNz6d.js.map → _server.ts-Bu3s5hfv.js.map} +1 -1
  74. package/build/server/chunks/{_server.ts-Cq9_scaV.js → _server.ts-CwAjt91u.js} +18 -18
  75. package/build/server/chunks/_server.ts-CwAjt91u.js.map +1 -0
  76. package/build/server/chunks/{_server.ts-CFX-S_8q.js → _server.ts-DZ5naqSL.js} +2 -2
  77. package/build/server/chunks/{_server.ts-CFX-S_8q.js.map → _server.ts-DZ5naqSL.js.map} +1 -1
  78. package/build/server/chunks/{_server.ts-Dekgb6Hx.js → _server.ts-DZP2lhaY.js} +3 -3
  79. package/build/server/chunks/{_server.ts-Dekgb6Hx.js.map → _server.ts-DZP2lhaY.js.map} +1 -1
  80. package/build/server/chunks/_server.ts-DZgfQKiH.js +81 -0
  81. package/build/server/chunks/_server.ts-DZgfQKiH.js.map +1 -0
  82. package/build/server/chunks/{_server.ts-CjK0g9dO.js → _server.ts-MbnroWEF.js} +25 -16
  83. package/build/server/chunks/_server.ts-MbnroWEF.js.map +1 -0
  84. package/build/server/chunks/{pty-manager-aFpChJah.js → pty-manager-DmNSCKAr.js} +99 -2
  85. package/build/server/chunks/pty-manager-DmNSCKAr.js.map +1 -0
  86. package/build/server/chunks/qwen-reader-DGfUbKaJ.js +2112 -0
  87. package/build/server/chunks/qwen-reader-DGfUbKaJ.js.map +1 -0
  88. package/build/server/chunks/{_server.ts-D--_NXt2.js → registry-Kcw2UCMv.js} +132 -106
  89. package/build/server/chunks/registry-Kcw2UCMv.js.map +1 -0
  90. package/build/server/index.js +1 -1
  91. package/build/server/index.js.map +1 -1
  92. package/build/server/manifest.js +16 -16
  93. package/build/server/manifest.js.map +1 -1
  94. package/package.json +2 -2
  95. package/scripts/e2e-all-features.sh +165 -0
  96. package/scripts/e2e-cross-terminal.sh +168 -0
  97. package/server.ts +12 -0
  98. package/src/lib/modules/client/common/index.ts +1 -1
  99. package/src/lib/modules/client/common/provider.ts +11 -0
  100. package/src/lib/modules/client/terminal/ChatView.svelte +9 -2
  101. package/src/lib/modules/client/terminal/LaunchSheet.svelte +4 -0
  102. package/src/lib/modules/server/sessions/amp-reader.ts +439 -0
  103. package/src/lib/modules/server/sessions/codex-reader.ts +34 -33
  104. package/src/lib/modules/server/sessions/copilot-reader.ts +542 -0
  105. package/src/lib/modules/server/sessions/cursor-reader.ts +634 -0
  106. package/src/lib/modules/server/sessions/gemini-reader.ts +594 -0
  107. package/src/lib/modules/server/sessions/opencode-db-path.ts +19 -10
  108. package/src/lib/modules/server/sessions/opencode-reader.ts +13 -12
  109. package/src/lib/modules/server/sessions/process-detector.ts +39 -18
  110. package/src/lib/modules/server/sessions/provider-paths.ts +173 -0
  111. package/src/lib/modules/server/sessions/qwen-reader.ts +336 -0
  112. package/src/lib/modules/server/sessions/registry.ts +178 -0
  113. package/src/lib/modules/server/terminal/codex-watcher.ts +4 -1
  114. package/src/lib/modules/server/terminal/generic-session-watcher.ts +163 -0
  115. package/src/lib/modules/server/terminal/pty-manager.ts +51 -0
  116. package/src/lib/modules/server/ws/session-handler.ts +34 -20
  117. package/src/lib/theme.css +32 -0
  118. package/src/lib/types/gemini.ts +100 -0
  119. package/src/lib/types/generated/Sessions.ts +17 -1
  120. package/src/lib/types/index.ts +1 -0
  121. package/src/lib/types/server.ts +23 -6
  122. package/src/lib/types/sessions.ts +14 -2
  123. package/src/routes/api/sessions/+server.ts +5 -52
  124. package/src/routes/api/sessions/connect/+server.ts +18 -11
  125. package/src/routes/api/terminals/+server.ts +7 -5
  126. package/src/routes/terminals/+page.svelte +7 -2
  127. package/src/routes/terminals/[id]/+page.svelte +1 -2
  128. package/build/client/_app/immutable/assets/0.DEfoFaGR.css.br +0 -0
  129. package/build/client/_app/immutable/assets/0.DEfoFaGR.css.gz +0 -0
  130. package/build/client/_app/immutable/chunks/Bkqjn62J.js +0 -1
  131. package/build/client/_app/immutable/chunks/Bkqjn62J.js.br +0 -1
  132. package/build/client/_app/immutable/chunks/Bkqjn62J.js.gz +0 -0
  133. package/build/client/_app/immutable/chunks/DOHhmtDH.js +0 -3
  134. package/build/client/_app/immutable/chunks/DOHhmtDH.js.br +0 -0
  135. package/build/client/_app/immutable/chunks/DOHhmtDH.js.gz +0 -0
  136. package/build/client/_app/immutable/chunks/DlS3abGJ.js.br +0 -0
  137. package/build/client/_app/immutable/chunks/DlS3abGJ.js.gz +0 -0
  138. package/build/client/_app/immutable/chunks/Pw0jDB7M.js +0 -1
  139. package/build/client/_app/immutable/chunks/Pw0jDB7M.js.br +0 -0
  140. package/build/client/_app/immutable/chunks/Pw0jDB7M.js.gz +0 -0
  141. package/build/client/_app/immutable/entry/app.CSJG7N9H.js.br +0 -0
  142. package/build/client/_app/immutable/entry/app.CSJG7N9H.js.gz +0 -0
  143. package/build/client/_app/immutable/entry/start.CTt1901T.js +0 -1
  144. package/build/client/_app/immutable/entry/start.CTt1901T.js.br +0 -2
  145. package/build/client/_app/immutable/entry/start.CTt1901T.js.gz +0 -0
  146. package/build/client/_app/immutable/nodes/0.qOL7xtFn.js.br +0 -0
  147. package/build/client/_app/immutable/nodes/0.qOL7xtFn.js.gz +0 -0
  148. package/build/client/_app/immutable/nodes/1.Di708Ago.js.br +0 -0
  149. package/build/client/_app/immutable/nodes/1.Di708Ago.js.gz +0 -0
  150. package/build/client/_app/immutable/nodes/2.DSM1znqa.js.br +0 -0
  151. package/build/client/_app/immutable/nodes/2.DSM1znqa.js.gz +0 -0
  152. package/build/client/_app/immutable/nodes/3.BPa5fh75.js.br +0 -0
  153. package/build/client/_app/immutable/nodes/3.BPa5fh75.js.gz +0 -0
  154. package/build/client/_app/immutable/nodes/6.B1LwwEF-.js +0 -1
  155. package/build/client/_app/immutable/nodes/6.B1LwwEF-.js.br +0 -0
  156. package/build/client/_app/immutable/nodes/6.B1LwwEF-.js.gz +0 -0
  157. package/build/client/_app/immutable/nodes/7.B7UJd8GQ.js.br +0 -0
  158. package/build/client/_app/immutable/nodes/7.B7UJd8GQ.js.gz +0 -0
  159. package/build/client/_app/immutable/nodes/8.CG0mrgBU.js +0 -2
  160. package/build/client/_app/immutable/nodes/8.CG0mrgBU.js.br +0 -0
  161. package/build/client/_app/immutable/nodes/8.CG0mrgBU.js.gz +0 -0
  162. package/build/client/_app/immutable/nodes/9.KwzWaMHj.js +0 -2
  163. package/build/client/_app/immutable/nodes/9.KwzWaMHj.js.br +0 -0
  164. package/build/client/_app/immutable/nodes/9.KwzWaMHj.js.gz +0 -0
  165. package/build/server/chunks/6-bPDbH1_W.js.map +0 -1
  166. package/build/server/chunks/7-CpBrOkxQ.js.map +0 -1
  167. package/build/server/chunks/8-BRGAVfze.js.map +0 -1
  168. package/build/server/chunks/9-C6xuAb_Y.js.map +0 -1
  169. package/build/server/chunks/_server.ts-BrRZXr-8.js.map +0 -1
  170. package/build/server/chunks/_server.ts-CjK0g9dO.js.map +0 -1
  171. package/build/server/chunks/_server.ts-Cq9_scaV.js.map +0 -1
  172. package/build/server/chunks/_server.ts-D--_NXt2.js.map +0 -1
  173. package/build/server/chunks/opencode-db-path-CRgzBK5U.js +0 -402
  174. package/build/server/chunks/opencode-db-path-CRgzBK5U.js.map +0 -1
  175. package/build/server/chunks/pty-manager-aFpChJah.js.map +0 -1
@@ -10,18 +10,18 @@ return {
10
10
  assets: new Set(["app-icon.png","apple-touch-icon.png","favicon.png","favicon.svg","manifest.json","pwa-192x192.png","pwa-512x512.png"]),
11
11
  mimeTypes: {".png":"image/png",".svg":"image/svg+xml",".json":"application/json"},
12
12
  _: {
13
- client: {start:"_app/immutable/entry/start.CTt1901T.js",app:"_app/immutable/entry/app.CSJG7N9H.js",imports:["_app/immutable/entry/start.CTt1901T.js","_app/immutable/chunks/DOHhmtDH.js","_app/immutable/chunks/DYuMZGL5.js","_app/immutable/entry/app.CSJG7N9H.js","_app/immutable/chunks/PPVm8Dsz.js","_app/immutable/chunks/DYuMZGL5.js","_app/immutable/chunks/Cg3dlX05.js"],stylesheets:[],fonts:[],uses_env_dynamic_public:false},
13
+ client: {start:"_app/immutable/entry/start.BVDjNnXt.js",app:"_app/immutable/entry/app.f46Ko1hu.js",imports:["_app/immutable/entry/start.BVDjNnXt.js","_app/immutable/chunks/nWG9RHyB.js","_app/immutable/chunks/DYuMZGL5.js","_app/immutable/entry/app.f46Ko1hu.js","_app/immutable/chunks/PPVm8Dsz.js","_app/immutable/chunks/DYuMZGL5.js","_app/immutable/chunks/Cg3dlX05.js"],stylesheets:[],fonts:[],uses_env_dynamic_public:false},
14
14
  nodes: [
15
- __memo(() => import('./chunks/0-D8uPamNd.js')),
16
- __memo(() => import('./chunks/1-DhtioHbs.js')),
17
- __memo(() => import('./chunks/2-Cgh7ZFgE.js')),
18
- __memo(() => import('./chunks/3-I6hnjssH.js')),
15
+ __memo(() => import('./chunks/0-Cd7jY0a7.js')),
16
+ __memo(() => import('./chunks/1-C4BOGoJY.js')),
17
+ __memo(() => import('./chunks/2-Ba0mNwJ6.js')),
18
+ __memo(() => import('./chunks/3-Pg8t1uJU.js')),
19
19
  __memo(() => import('./chunks/4-BtYdKCVW.js')),
20
20
  __memo(() => import('./chunks/5-CvJK3PiH.js')),
21
- __memo(() => import('./chunks/6-bPDbH1_W.js')),
22
- __memo(() => import('./chunks/7-CpBrOkxQ.js')),
23
- __memo(() => import('./chunks/8-BRGAVfze.js')),
24
- __memo(() => import('./chunks/9-C6xuAb_Y.js'))
21
+ __memo(() => import('./chunks/6-D8xbnTSo.js')),
22
+ __memo(() => import('./chunks/7-CkVK06S0.js')),
23
+ __memo(() => import('./chunks/8-C8qVhrds.js')),
24
+ __memo(() => import('./chunks/9-fL5zqN0T.js'))
25
25
  ],
26
26
  remotes: {
27
27
 
@@ -81,7 +81,7 @@ return {
81
81
  pattern: /^\/api\/notify\/?$/,
82
82
  params: [],
83
83
  page: null,
84
- endpoint: __memo(() => import('./chunks/_server.ts-CFX-S_8q.js'))
84
+ endpoint: __memo(() => import('./chunks/_server.ts-DZ5naqSL.js'))
85
85
  },
86
86
  {
87
87
  id: "/api/qr-config",
@@ -102,35 +102,35 @@ return {
102
102
  pattern: /^\/api\/sessions\/?$/,
103
103
  params: [],
104
104
  page: null,
105
- endpoint: __memo(() => import('./chunks/_server.ts-D--_NXt2.js'))
105
+ endpoint: __memo(() => import('./chunks/_server.ts-DZgfQKiH.js'))
106
106
  },
107
107
  {
108
108
  id: "/api/sessions/connect",
109
109
  pattern: /^\/api\/sessions\/connect\/?$/,
110
110
  params: [],
111
111
  page: null,
112
- endpoint: __memo(() => import('./chunks/_server.ts-Cq9_scaV.js'))
112
+ endpoint: __memo(() => import('./chunks/_server.ts-CwAjt91u.js'))
113
113
  },
114
114
  {
115
115
  id: "/api/sessions/detect",
116
116
  pattern: /^\/api\/sessions\/detect\/?$/,
117
117
  params: [],
118
118
  page: null,
119
- endpoint: __memo(() => import('./chunks/_server.ts-CjK0g9dO.js'))
119
+ endpoint: __memo(() => import('./chunks/_server.ts-MbnroWEF.js'))
120
120
  },
121
121
  {
122
122
  id: "/api/terminals",
123
123
  pattern: /^\/api\/terminals\/?$/,
124
124
  params: [],
125
125
  page: null,
126
- endpoint: __memo(() => import('./chunks/_server.ts-BrRZXr-8.js'))
126
+ endpoint: __memo(() => import('./chunks/_server.ts-BA_uWcPw.js'))
127
127
  },
128
128
  {
129
129
  id: "/api/terminals/[id]",
130
130
  pattern: /^\/api\/terminals\/([^/]+?)\/?$/,
131
131
  params: [{"name":"id","optional":false,"rest":false,"chained":false}],
132
132
  page: null,
133
- endpoint: __memo(() => import('./chunks/_server.ts-Dekgb6Hx.js'))
133
+ endpoint: __memo(() => import('./chunks/_server.ts-DZP2lhaY.js'))
134
134
  },
135
135
  {
136
136
  id: "/api/terminals/[id]/paste-image",
@@ -144,7 +144,7 @@ return {
144
144
  pattern: /^\/api\/terminals\/([^/]+?)\/resize\/?$/,
145
145
  params: [{"name":"id","optional":false,"rest":false,"chained":false}],
146
146
  page: null,
147
- endpoint: __memo(() => import('./chunks/_server.ts-C6xbNz6d.js'))
147
+ endpoint: __memo(() => import('./chunks/_server.ts-Bu3s5hfv.js'))
148
148
  },
149
149
  {
150
150
  id: "/api/webhook",
@@ -1 +1 @@
1
- {"version":3,"file":"manifest.js","sources":["../../.svelte-kit/adapter-node/manifest.js"],"sourcesContent":["export const manifest = (() => {\nfunction __memo(fn) {\n\tlet value;\n\treturn () => value ??= (value = fn());\n}\n\nreturn {\n\tappDir: \"_app\",\n\tappPath: \"_app\",\n\tassets: new Set([\"app-icon.png\",\"apple-touch-icon.png\",\"favicon.png\",\"favicon.svg\",\"manifest.json\",\"pwa-192x192.png\",\"pwa-512x512.png\"]),\n\tmimeTypes: {\".png\":\"image/png\",\".svg\":\"image/svg+xml\",\".json\":\"application/json\"},\n\t_: {\n\t\tclient: {start:\"_app/immutable/entry/start.CTt1901T.js\",app:\"_app/immutable/entry/app.CSJG7N9H.js\",imports:[\"_app/immutable/entry/start.CTt1901T.js\",\"_app/immutable/chunks/DOHhmtDH.js\",\"_app/immutable/chunks/DYuMZGL5.js\",\"_app/immutable/entry/app.CSJG7N9H.js\",\"_app/immutable/chunks/PPVm8Dsz.js\",\"_app/immutable/chunks/DYuMZGL5.js\",\"_app/immutable/chunks/Cg3dlX05.js\"],stylesheets:[],fonts:[],uses_env_dynamic_public:false},\n\t\tnodes: [\n\t\t\t__memo(() => import('./nodes/0.js')),\n\t\t\t__memo(() => import('./nodes/1.js')),\n\t\t\t__memo(() => import('./nodes/2.js')),\n\t\t\t__memo(() => import('./nodes/3.js')),\n\t\t\t__memo(() => import('./nodes/4.js')),\n\t\t\t__memo(() => import('./nodes/5.js')),\n\t\t\t__memo(() => import('./nodes/6.js')),\n\t\t\t__memo(() => import('./nodes/7.js')),\n\t\t\t__memo(() => import('./nodes/8.js')),\n\t\t\t__memo(() => import('./nodes/9.js'))\n\t\t],\n\t\tremotes: {\n\t\t\t\n\t\t},\n\t\troutes: [\n\t\t\t{\n\t\t\t\tid: \"/\",\n\t\t\t\tpattern: /^\\/$/,\n\t\t\t\tparams: [],\n\t\t\t\tpage: { layouts: [0,], errors: [1,], leaf: 2 },\n\t\t\t\tendpoint: null\n\t\t\t},\n\t\t\t{\n\t\t\t\tid: \"/activity\",\n\t\t\t\tpattern: /^\\/activity\\/?$/,\n\t\t\t\tparams: [],\n\t\t\t\tpage: { layouts: [0,], errors: [1,], leaf: 3 },\n\t\t\t\tendpoint: null\n\t\t\t},\n\t\t\t{\n\t\t\t\tid: \"/api/debug\",\n\t\t\t\tpattern: /^\\/api\\/debug\\/?$/,\n\t\t\t\tparams: [],\n\t\t\t\tpage: null,\n\t\t\t\tendpoint: __memo(() => import('./entries/endpoints/api/debug/_server.ts.js'))\n\t\t\t},\n\t\t\t{\n\t\t\t\tid: \"/api/decide/[requestId]\",\n\t\t\t\tpattern: /^\\/api\\/decide\\/([^/]+?)\\/?$/,\n\t\t\t\tparams: [{\"name\":\"requestId\",\"optional\":false,\"rest\":false,\"chained\":false}],\n\t\t\t\tpage: null,\n\t\t\t\tendpoint: __memo(() => import('./entries/endpoints/api/decide/_requestId_/_server.ts.js'))\n\t\t\t},\n\t\t\t{\n\t\t\t\tid: \"/api/device-token\",\n\t\t\t\tpattern: /^\\/api\\/device-token\\/?$/,\n\t\t\t\tparams: [],\n\t\t\t\tpage: null,\n\t\t\t\tendpoint: __memo(() => import('./entries/endpoints/api/device-token/_server.ts.js'))\n\t\t\t},\n\t\t\t{\n\t\t\t\tid: \"/api/health\",\n\t\t\t\tpattern: /^\\/api\\/health\\/?$/,\n\t\t\t\tparams: [],\n\t\t\t\tpage: null,\n\t\t\t\tendpoint: __memo(() => import('./entries/endpoints/api/health/_server.ts.js'))\n\t\t\t},\n\t\t\t{\n\t\t\t\tid: \"/api/neurolink-proxy\",\n\t\t\t\tpattern: /^\\/api\\/neurolink-proxy\\/?$/,\n\t\t\t\tparams: [],\n\t\t\t\tpage: null,\n\t\t\t\tendpoint: __memo(() => import('./entries/endpoints/api/neurolink-proxy/_server.ts.js'))\n\t\t\t},\n\t\t\t{\n\t\t\t\tid: \"/api/notify\",\n\t\t\t\tpattern: /^\\/api\\/notify\\/?$/,\n\t\t\t\tparams: [],\n\t\t\t\tpage: null,\n\t\t\t\tendpoint: __memo(() => import('./entries/endpoints/api/notify/_server.ts.js'))\n\t\t\t},\n\t\t\t{\n\t\t\t\tid: \"/api/qr-config\",\n\t\t\t\tpattern: /^\\/api\\/qr-config\\/?$/,\n\t\t\t\tparams: [],\n\t\t\t\tpage: null,\n\t\t\t\tendpoint: __memo(() => import('./entries/endpoints/api/qr-config/_server.ts.js'))\n\t\t\t},\n\t\t\t{\n\t\t\t\tid: \"/api/response\",\n\t\t\t\tpattern: /^\\/api\\/response\\/?$/,\n\t\t\t\tparams: [],\n\t\t\t\tpage: null,\n\t\t\t\tendpoint: __memo(() => import('./entries/endpoints/api/response/_server.ts.js'))\n\t\t\t},\n\t\t\t{\n\t\t\t\tid: \"/api/sessions\",\n\t\t\t\tpattern: /^\\/api\\/sessions\\/?$/,\n\t\t\t\tparams: [],\n\t\t\t\tpage: null,\n\t\t\t\tendpoint: __memo(() => import('./entries/endpoints/api/sessions/_server.ts.js'))\n\t\t\t},\n\t\t\t{\n\t\t\t\tid: \"/api/sessions/connect\",\n\t\t\t\tpattern: /^\\/api\\/sessions\\/connect\\/?$/,\n\t\t\t\tparams: [],\n\t\t\t\tpage: null,\n\t\t\t\tendpoint: __memo(() => import('./entries/endpoints/api/sessions/connect/_server.ts.js'))\n\t\t\t},\n\t\t\t{\n\t\t\t\tid: \"/api/sessions/detect\",\n\t\t\t\tpattern: /^\\/api\\/sessions\\/detect\\/?$/,\n\t\t\t\tparams: [],\n\t\t\t\tpage: null,\n\t\t\t\tendpoint: __memo(() => import('./entries/endpoints/api/sessions/detect/_server.ts.js'))\n\t\t\t},\n\t\t\t{\n\t\t\t\tid: \"/api/terminals\",\n\t\t\t\tpattern: /^\\/api\\/terminals\\/?$/,\n\t\t\t\tparams: [],\n\t\t\t\tpage: null,\n\t\t\t\tendpoint: __memo(() => import('./entries/endpoints/api/terminals/_server.ts.js'))\n\t\t\t},\n\t\t\t{\n\t\t\t\tid: \"/api/terminals/[id]\",\n\t\t\t\tpattern: /^\\/api\\/terminals\\/([^/]+?)\\/?$/,\n\t\t\t\tparams: [{\"name\":\"id\",\"optional\":false,\"rest\":false,\"chained\":false}],\n\t\t\t\tpage: null,\n\t\t\t\tendpoint: __memo(() => import('./entries/endpoints/api/terminals/_id_/_server.ts.js'))\n\t\t\t},\n\t\t\t{\n\t\t\t\tid: \"/api/terminals/[id]/paste-image\",\n\t\t\t\tpattern: /^\\/api\\/terminals\\/([^/]+?)\\/paste-image\\/?$/,\n\t\t\t\tparams: [{\"name\":\"id\",\"optional\":false,\"rest\":false,\"chained\":false}],\n\t\t\t\tpage: null,\n\t\t\t\tendpoint: __memo(() => import('./entries/endpoints/api/terminals/_id_/paste-image/_server.ts.js'))\n\t\t\t},\n\t\t\t{\n\t\t\t\tid: \"/api/terminals/[id]/resize\",\n\t\t\t\tpattern: /^\\/api\\/terminals\\/([^/]+?)\\/resize\\/?$/,\n\t\t\t\tparams: [{\"name\":\"id\",\"optional\":false,\"rest\":false,\"chained\":false}],\n\t\t\t\tpage: null,\n\t\t\t\tendpoint: __memo(() => import('./entries/endpoints/api/terminals/_id_/resize/_server.ts.js'))\n\t\t\t},\n\t\t\t{\n\t\t\t\tid: \"/api/webhook\",\n\t\t\t\tpattern: /^\\/api\\/webhook\\/?$/,\n\t\t\t\tparams: [],\n\t\t\t\tpage: null,\n\t\t\t\tendpoint: __memo(() => import('./entries/endpoints/api/webhook/_server.ts.js'))\n\t\t\t},\n\t\t\t{\n\t\t\t\tid: \"/api/ws-status\",\n\t\t\t\tpattern: /^\\/api\\/ws-status\\/?$/,\n\t\t\t\tparams: [],\n\t\t\t\tpage: null,\n\t\t\t\tendpoint: __memo(() => import('./entries/endpoints/api/ws-status/_server.ts.js'))\n\t\t\t},\n\t\t\t{\n\t\t\t\tid: \"/api/ws-ticket\",\n\t\t\t\tpattern: /^\\/api\\/ws-ticket\\/?$/,\n\t\t\t\tparams: [],\n\t\t\t\tpage: null,\n\t\t\t\tendpoint: __memo(() => import('./entries/endpoints/api/ws-ticket/_server.ts.js'))\n\t\t\t},\n\t\t\t{\n\t\t\t\tid: \"/config\",\n\t\t\t\tpattern: /^\\/config\\/?$/,\n\t\t\t\tparams: [],\n\t\t\t\tpage: { layouts: [0,], errors: [1,], leaf: 4 },\n\t\t\t\tendpoint: null\n\t\t\t},\n\t\t\t{\n\t\t\t\tid: \"/neurolink\",\n\t\t\t\tpattern: /^\\/neurolink\\/?$/,\n\t\t\t\tparams: [],\n\t\t\t\tpage: { layouts: [0,], errors: [1,], leaf: 5 },\n\t\t\t\tendpoint: null\n\t\t\t},\n\t\t\t{\n\t\t\t\tid: \"/project\",\n\t\t\t\tpattern: /^\\/project\\/?$/,\n\t\t\t\tparams: [],\n\t\t\t\tpage: { layouts: [0,], errors: [1,], leaf: 6 },\n\t\t\t\tendpoint: null\n\t\t\t},\n\t\t\t{\n\t\t\t\tid: \"/session/[id]\",\n\t\t\t\tpattern: /^\\/session\\/([^/]+?)\\/?$/,\n\t\t\t\tparams: [{\"name\":\"id\",\"optional\":false,\"rest\":false,\"chained\":false}],\n\t\t\t\tpage: { layouts: [0,], errors: [1,], leaf: 7 },\n\t\t\t\tendpoint: null\n\t\t\t},\n\t\t\t{\n\t\t\t\tid: \"/terminals\",\n\t\t\t\tpattern: /^\\/terminals\\/?$/,\n\t\t\t\tparams: [],\n\t\t\t\tpage: { layouts: [0,], errors: [1,], leaf: 8 },\n\t\t\t\tendpoint: null\n\t\t\t},\n\t\t\t{\n\t\t\t\tid: \"/terminals/[id]\",\n\t\t\t\tpattern: /^\\/terminals\\/([^/]+?)\\/?$/,\n\t\t\t\tparams: [{\"name\":\"id\",\"optional\":false,\"rest\":false,\"chained\":false}],\n\t\t\t\tpage: { layouts: [0,], errors: [1,], leaf: 9 },\n\t\t\t\tendpoint: null\n\t\t\t}\n\t\t],\n\t\tprerendered_routes: new Set([]),\n\t\tmatchers: async () => {\n\t\t\t\n\t\t\treturn { };\n\t\t},\n\t\tserver_assets: {}\n\t}\n}\n})();\n\nexport const prerendered = new Set([]);\n\nexport const base = \"\";"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"manifest.js","sources":["../../.svelte-kit/adapter-node/manifest.js"],"sourcesContent":["export const manifest = (() => {\nfunction __memo(fn) {\n\tlet value;\n\treturn () => value ??= (value = fn());\n}\n\nreturn {\n\tappDir: \"_app\",\n\tappPath: \"_app\",\n\tassets: new Set([\"app-icon.png\",\"apple-touch-icon.png\",\"favicon.png\",\"favicon.svg\",\"manifest.json\",\"pwa-192x192.png\",\"pwa-512x512.png\"]),\n\tmimeTypes: {\".png\":\"image/png\",\".svg\":\"image/svg+xml\",\".json\":\"application/json\"},\n\t_: {\n\t\tclient: {start:\"_app/immutable/entry/start.BVDjNnXt.js\",app:\"_app/immutable/entry/app.f46Ko1hu.js\",imports:[\"_app/immutable/entry/start.BVDjNnXt.js\",\"_app/immutable/chunks/nWG9RHyB.js\",\"_app/immutable/chunks/DYuMZGL5.js\",\"_app/immutable/entry/app.f46Ko1hu.js\",\"_app/immutable/chunks/PPVm8Dsz.js\",\"_app/immutable/chunks/DYuMZGL5.js\",\"_app/immutable/chunks/Cg3dlX05.js\"],stylesheets:[],fonts:[],uses_env_dynamic_public:false},\n\t\tnodes: [\n\t\t\t__memo(() => import('./nodes/0.js')),\n\t\t\t__memo(() => import('./nodes/1.js')),\n\t\t\t__memo(() => import('./nodes/2.js')),\n\t\t\t__memo(() => import('./nodes/3.js')),\n\t\t\t__memo(() => import('./nodes/4.js')),\n\t\t\t__memo(() => import('./nodes/5.js')),\n\t\t\t__memo(() => import('./nodes/6.js')),\n\t\t\t__memo(() => import('./nodes/7.js')),\n\t\t\t__memo(() => import('./nodes/8.js')),\n\t\t\t__memo(() => import('./nodes/9.js'))\n\t\t],\n\t\tremotes: {\n\t\t\t\n\t\t},\n\t\troutes: [\n\t\t\t{\n\t\t\t\tid: \"/\",\n\t\t\t\tpattern: /^\\/$/,\n\t\t\t\tparams: [],\n\t\t\t\tpage: { layouts: [0,], errors: [1,], leaf: 2 },\n\t\t\t\tendpoint: null\n\t\t\t},\n\t\t\t{\n\t\t\t\tid: \"/activity\",\n\t\t\t\tpattern: /^\\/activity\\/?$/,\n\t\t\t\tparams: [],\n\t\t\t\tpage: { layouts: [0,], errors: [1,], leaf: 3 },\n\t\t\t\tendpoint: null\n\t\t\t},\n\t\t\t{\n\t\t\t\tid: \"/api/debug\",\n\t\t\t\tpattern: /^\\/api\\/debug\\/?$/,\n\t\t\t\tparams: [],\n\t\t\t\tpage: null,\n\t\t\t\tendpoint: __memo(() => import('./entries/endpoints/api/debug/_server.ts.js'))\n\t\t\t},\n\t\t\t{\n\t\t\t\tid: \"/api/decide/[requestId]\",\n\t\t\t\tpattern: /^\\/api\\/decide\\/([^/]+?)\\/?$/,\n\t\t\t\tparams: [{\"name\":\"requestId\",\"optional\":false,\"rest\":false,\"chained\":false}],\n\t\t\t\tpage: null,\n\t\t\t\tendpoint: __memo(() => import('./entries/endpoints/api/decide/_requestId_/_server.ts.js'))\n\t\t\t},\n\t\t\t{\n\t\t\t\tid: \"/api/device-token\",\n\t\t\t\tpattern: /^\\/api\\/device-token\\/?$/,\n\t\t\t\tparams: [],\n\t\t\t\tpage: null,\n\t\t\t\tendpoint: __memo(() => import('./entries/endpoints/api/device-token/_server.ts.js'))\n\t\t\t},\n\t\t\t{\n\t\t\t\tid: \"/api/health\",\n\t\t\t\tpattern: /^\\/api\\/health\\/?$/,\n\t\t\t\tparams: [],\n\t\t\t\tpage: null,\n\t\t\t\tendpoint: __memo(() => import('./entries/endpoints/api/health/_server.ts.js'))\n\t\t\t},\n\t\t\t{\n\t\t\t\tid: \"/api/neurolink-proxy\",\n\t\t\t\tpattern: /^\\/api\\/neurolink-proxy\\/?$/,\n\t\t\t\tparams: [],\n\t\t\t\tpage: null,\n\t\t\t\tendpoint: __memo(() => import('./entries/endpoints/api/neurolink-proxy/_server.ts.js'))\n\t\t\t},\n\t\t\t{\n\t\t\t\tid: \"/api/notify\",\n\t\t\t\tpattern: /^\\/api\\/notify\\/?$/,\n\t\t\t\tparams: [],\n\t\t\t\tpage: null,\n\t\t\t\tendpoint: __memo(() => import('./entries/endpoints/api/notify/_server.ts.js'))\n\t\t\t},\n\t\t\t{\n\t\t\t\tid: \"/api/qr-config\",\n\t\t\t\tpattern: /^\\/api\\/qr-config\\/?$/,\n\t\t\t\tparams: [],\n\t\t\t\tpage: null,\n\t\t\t\tendpoint: __memo(() => import('./entries/endpoints/api/qr-config/_server.ts.js'))\n\t\t\t},\n\t\t\t{\n\t\t\t\tid: \"/api/response\",\n\t\t\t\tpattern: /^\\/api\\/response\\/?$/,\n\t\t\t\tparams: [],\n\t\t\t\tpage: null,\n\t\t\t\tendpoint: __memo(() => import('./entries/endpoints/api/response/_server.ts.js'))\n\t\t\t},\n\t\t\t{\n\t\t\t\tid: \"/api/sessions\",\n\t\t\t\tpattern: /^\\/api\\/sessions\\/?$/,\n\t\t\t\tparams: [],\n\t\t\t\tpage: null,\n\t\t\t\tendpoint: __memo(() => import('./entries/endpoints/api/sessions/_server.ts.js'))\n\t\t\t},\n\t\t\t{\n\t\t\t\tid: \"/api/sessions/connect\",\n\t\t\t\tpattern: /^\\/api\\/sessions\\/connect\\/?$/,\n\t\t\t\tparams: [],\n\t\t\t\tpage: null,\n\t\t\t\tendpoint: __memo(() => import('./entries/endpoints/api/sessions/connect/_server.ts.js'))\n\t\t\t},\n\t\t\t{\n\t\t\t\tid: \"/api/sessions/detect\",\n\t\t\t\tpattern: /^\\/api\\/sessions\\/detect\\/?$/,\n\t\t\t\tparams: [],\n\t\t\t\tpage: null,\n\t\t\t\tendpoint: __memo(() => import('./entries/endpoints/api/sessions/detect/_server.ts.js'))\n\t\t\t},\n\t\t\t{\n\t\t\t\tid: \"/api/terminals\",\n\t\t\t\tpattern: /^\\/api\\/terminals\\/?$/,\n\t\t\t\tparams: [],\n\t\t\t\tpage: null,\n\t\t\t\tendpoint: __memo(() => import('./entries/endpoints/api/terminals/_server.ts.js'))\n\t\t\t},\n\t\t\t{\n\t\t\t\tid: \"/api/terminals/[id]\",\n\t\t\t\tpattern: /^\\/api\\/terminals\\/([^/]+?)\\/?$/,\n\t\t\t\tparams: [{\"name\":\"id\",\"optional\":false,\"rest\":false,\"chained\":false}],\n\t\t\t\tpage: null,\n\t\t\t\tendpoint: __memo(() => import('./entries/endpoints/api/terminals/_id_/_server.ts.js'))\n\t\t\t},\n\t\t\t{\n\t\t\t\tid: \"/api/terminals/[id]/paste-image\",\n\t\t\t\tpattern: /^\\/api\\/terminals\\/([^/]+?)\\/paste-image\\/?$/,\n\t\t\t\tparams: [{\"name\":\"id\",\"optional\":false,\"rest\":false,\"chained\":false}],\n\t\t\t\tpage: null,\n\t\t\t\tendpoint: __memo(() => import('./entries/endpoints/api/terminals/_id_/paste-image/_server.ts.js'))\n\t\t\t},\n\t\t\t{\n\t\t\t\tid: \"/api/terminals/[id]/resize\",\n\t\t\t\tpattern: /^\\/api\\/terminals\\/([^/]+?)\\/resize\\/?$/,\n\t\t\t\tparams: [{\"name\":\"id\",\"optional\":false,\"rest\":false,\"chained\":false}],\n\t\t\t\tpage: null,\n\t\t\t\tendpoint: __memo(() => import('./entries/endpoints/api/terminals/_id_/resize/_server.ts.js'))\n\t\t\t},\n\t\t\t{\n\t\t\t\tid: \"/api/webhook\",\n\t\t\t\tpattern: /^\\/api\\/webhook\\/?$/,\n\t\t\t\tparams: [],\n\t\t\t\tpage: null,\n\t\t\t\tendpoint: __memo(() => import('./entries/endpoints/api/webhook/_server.ts.js'))\n\t\t\t},\n\t\t\t{\n\t\t\t\tid: \"/api/ws-status\",\n\t\t\t\tpattern: /^\\/api\\/ws-status\\/?$/,\n\t\t\t\tparams: [],\n\t\t\t\tpage: null,\n\t\t\t\tendpoint: __memo(() => import('./entries/endpoints/api/ws-status/_server.ts.js'))\n\t\t\t},\n\t\t\t{\n\t\t\t\tid: \"/api/ws-ticket\",\n\t\t\t\tpattern: /^\\/api\\/ws-ticket\\/?$/,\n\t\t\t\tparams: [],\n\t\t\t\tpage: null,\n\t\t\t\tendpoint: __memo(() => import('./entries/endpoints/api/ws-ticket/_server.ts.js'))\n\t\t\t},\n\t\t\t{\n\t\t\t\tid: \"/config\",\n\t\t\t\tpattern: /^\\/config\\/?$/,\n\t\t\t\tparams: [],\n\t\t\t\tpage: { layouts: [0,], errors: [1,], leaf: 4 },\n\t\t\t\tendpoint: null\n\t\t\t},\n\t\t\t{\n\t\t\t\tid: \"/neurolink\",\n\t\t\t\tpattern: /^\\/neurolink\\/?$/,\n\t\t\t\tparams: [],\n\t\t\t\tpage: { layouts: [0,], errors: [1,], leaf: 5 },\n\t\t\t\tendpoint: null\n\t\t\t},\n\t\t\t{\n\t\t\t\tid: \"/project\",\n\t\t\t\tpattern: /^\\/project\\/?$/,\n\t\t\t\tparams: [],\n\t\t\t\tpage: { layouts: [0,], errors: [1,], leaf: 6 },\n\t\t\t\tendpoint: null\n\t\t\t},\n\t\t\t{\n\t\t\t\tid: \"/session/[id]\",\n\t\t\t\tpattern: /^\\/session\\/([^/]+?)\\/?$/,\n\t\t\t\tparams: [{\"name\":\"id\",\"optional\":false,\"rest\":false,\"chained\":false}],\n\t\t\t\tpage: { layouts: [0,], errors: [1,], leaf: 7 },\n\t\t\t\tendpoint: null\n\t\t\t},\n\t\t\t{\n\t\t\t\tid: \"/terminals\",\n\t\t\t\tpattern: /^\\/terminals\\/?$/,\n\t\t\t\tparams: [],\n\t\t\t\tpage: { layouts: [0,], errors: [1,], leaf: 8 },\n\t\t\t\tendpoint: null\n\t\t\t},\n\t\t\t{\n\t\t\t\tid: \"/terminals/[id]\",\n\t\t\t\tpattern: /^\\/terminals\\/([^/]+?)\\/?$/,\n\t\t\t\tparams: [{\"name\":\"id\",\"optional\":false,\"rest\":false,\"chained\":false}],\n\t\t\t\tpage: { layouts: [0,], errors: [1,], leaf: 9 },\n\t\t\t\tendpoint: null\n\t\t\t}\n\t\t],\n\t\tprerendered_routes: new Set([]),\n\t\tmatchers: async () => {\n\t\t\t\n\t\t\treturn { };\n\t\t},\n\t\tserver_assets: {}\n\t}\n}\n})();\n\nexport const prerendered = new Set([]);\n\nexport const base = \"\";"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@juspay/shooter",
3
- "version": "1.16.0",
3
+ "version": "1.18.0",
4
4
  "description": "Bidirectional communication server for Claude Code and iOS — push notifications, remote terminal, session viewing",
5
5
  "type": "module",
6
6
  "packageManager": "pnpm@10.28.2",
@@ -76,7 +76,7 @@
76
76
  "format:generated": "prettier --write ./src/lib/types/generated/*",
77
77
  "quality:all": "pnpm run lint && pnpm run format:check && pnpm run check",
78
78
  "gen:types": "npx type-crafter generate typescript-with-decoders ./specs/types/index.yaml ./src/lib/types/generated SingleFile SingleFile && bash scripts/postgen-types.sh && pnpm run format:generated",
79
- "test": "node tests/terminal-store.test.cjs && node tests/pending-requests.test.cjs && node tests/tunnel-discovery.test.cjs && node tests/plan-mode-routing.test.cjs && node tests/dynamic-options-extraction.test.cjs && node tests/codex-parser.test.cjs",
79
+ "test": "node tests/terminal-store.test.cjs && node tests/pending-requests.test.cjs && node tests/tunnel-discovery.test.cjs && node tests/plan-mode-routing.test.cjs && node tests/dynamic-options-extraction.test.cjs && node tests/codex-parser.test.cjs && node tests/provider-readers.test.cjs && node tests/generic-watcher.test.cjs",
80
80
  "setup": "node scripts/setup.cjs",
81
81
  "prepare": "husky || true",
82
82
  "prepublishOnly": "pnpm build"
@@ -0,0 +1,165 @@
1
+ #!/usr/bin/env bash
2
+ # Shooter FULL-FEATURE end-to-end test.
3
+ #
4
+ # Exercises (not just renders) every HTTP route, all three WebSocket channels,
5
+ # the bidirectional permission loop, PTY I/O + resize + image paste, the
6
+ # multi-provider session API, and terminal persistence across a server restart.
7
+ # Run against a live build: API_KEY=<key> PORT=54007 bash scripts/e2e-all-features.sh
8
+ set -uo pipefail
9
+
10
+ PORT="${PORT:-54007}"
11
+ API_KEY="${API_KEY:-e2e-browser-key}"
12
+ BASE="http://localhost:${PORT}"
13
+ WSJS="$(pwd)/.e2e-allfeat-$$.mjs" # keep WS client in-project so `ws` resolves
14
+ LOG="/tmp/shooter-allfeat-$$.log"
15
+ PASS=0; FAIL=0
16
+ TERMS=""
17
+ A=(-H "Authorization: Bearer ${API_KEY}")
18
+ J=(-H "Content-Type: application/json")
19
+
20
+ ok(){ PASS=$((PASS+1)); printf ' \033[32m✓\033[0m %s\n' "$1"; }
21
+ no(){ FAIL=$((FAIL+1)); printf ' \033[31m✗\033[0m %s — %s\n' "$1" "$2"; }
22
+ hcode(){ curl -s -o /dev/null -w '%{http_code}' "$@"; }
23
+ jget(){ python3 -c "import json,sys;d=json.load(sys.stdin);print(eval(sys.argv[1]))" "$1" 2>/dev/null; }
24
+
25
+ cleanup(){
26
+ for t in $TERMS; do
27
+ curl -s -X DELETE "${A[@]}" "${BASE}/api/terminals/${t}" >/dev/null 2>&1 || true
28
+ pkill -f "pty-holder.cjs ${t}" 2>/dev/null || true
29
+ rm -f "/tmp/shooter-term-${t}.sock" 2>/dev/null || true
30
+ done
31
+ # Kill the server only if THIS script started it (leave a pre-existing external one).
32
+ [ -n "${SERVER_PID:-}" ] && kill "${SERVER_PID}" 2>/dev/null || true
33
+ rm -f "$WSJS" "$LOG"
34
+ }
35
+ trap cleanup EXIT
36
+
37
+ ensure_up(){ for i in $(seq 1 20); do [ "$(hcode "${A[@]}" "${BASE}/api/health")" = 200 ] && return 0; sleep 1; done; return 1; }
38
+ start_server(){ nohup env API_KEY="${API_KEY}" PORT="${PORT}" npx tsx server.ts >"$LOG" 2>&1 & SERVER_PID=$!; disown 2>/dev/null || true; }
39
+
40
+ echo "=== Shooter full-feature E2E (port ${PORT}) ==="
41
+ [ -f build/handler.js ] || { echo "build/handler.js missing — run pnpm build"; exit 1; }
42
+ ensure_up || { echo "server not up; starting"; start_server; ensure_up || { echo "FAILED to start"; exit 1; }; }
43
+
44
+ # ─────────────────────────────────────────────────────────────────────────
45
+ echo ""; echo "── 1. Auth + health/status/debug ──"
46
+ [ "$(hcode "${BASE}/api/sessions")" = 401 ] && ok "auth: unauth request → 401" || no "auth gate" "got $(hcode "${BASE}/api/sessions")"
47
+ [ "$(hcode "${A[@]}" "${BASE}/api/sessions")" = 200 ] && ok "auth: valid key → 200" || no "auth valid" "not 200"
48
+ curl -s "${A[@]}" "${BASE}/api/health" | grep -q '"status":"healthy"' && ok "/api/health healthy" || no "/api/health" "not healthy"
49
+ curl -s "${A[@]}" "${BASE}/api/ws-status" | grep -qE '\{' && ok "/api/ws-status returns JSON" || no "/api/ws-status" "no json"
50
+ curl -s "${A[@]}" "${BASE}/api/debug" | grep -q 'deviceToken' && ok "/api/debug returns diagnostics" || no "/api/debug" "no deviceToken field"
51
+
52
+ echo ""; echo "── 2. Pairing / device config ──"
53
+ QR=$(curl -s "${A[@]}" "${BASE}/api/qr-config")
54
+ echo "$QR" | grep -q 'data:image/png;base64' && ok "/api/qr-config returns QR data URL" || no "/api/qr-config" "no QR dataUrl"
55
+ echo "$QR" | grep -q 'serverUrl' && ok "/api/qr-config returns serverUrl" || no "/api/qr-config serverUrl" "missing"
56
+ DT=$(hcode "${A[@]}" "${J[@]}" -X POST -d '{"platform":"ios","deviceToken":"'"$(printf 'a%.0s' {1..64})"'"}' "${BASE}/api/device-token")
57
+ [ "$DT" = 200 ] && ok "/api/device-token registers token" || no "/api/device-token" "got $DT"
58
+ [ "$(hcode "${A[@]}" "${J[@]}" -X POST -d '{"platform":"ios"}' "${BASE}/api/device-token")" = 400 ] && ok "/api/device-token validates missing token (400)" || no "device-token validation" "no 400"
59
+
60
+ echo ""; echo "── 3. Notifications + webhook ──"
61
+ NOT=$(hcode "${A[@]}" "${J[@]}" -X POST -d '{"title":"E2E","message":"hello"}' "${BASE}/api/notify")
62
+ [ "$NOT" = 200 ] && ok "/api/notify accepts notification (200)" || no "/api/notify" "got $NOT"
63
+ [ "$(hcode "${A[@]}" "${J[@]}" -X POST -d '{"message":"no title"}' "${BASE}/api/notify")" = 400 ] && ok "/api/notify validates required fields (400)" || no "notify validation" "no 400"
64
+ [ "$(hcode "${A[@]}" "${J[@]}" -X POST -d '{}' "${BASE}/api/webhook")" = 501 ] && ok "/api/webhook stub returns 501" || no "/api/webhook" "expected 501"
65
+
66
+ echo ""; echo "── 4. NeuroLink proxy (allowlist enforcement) ──"
67
+ NP=$(hcode "${A[@]}" "${J[@]}" -X POST -d '{"provider":"evil","url":"http://attacker.test/x","headers":{}}' "${BASE}/api/neurolink-proxy")
68
+ [ "$NP" = 403 ] && ok "/api/neurolink-proxy blocks non-allowlisted URL (403)" || no "neurolink-proxy allowlist" "got $NP"
69
+ [ "$(hcode "${A[@]}" "${J[@]}" -X POST -d '{"provider":"openai"}' "${BASE}/api/neurolink-proxy")" = 400 ] && ok "/api/neurolink-proxy validates malformed payload (400)" || no "neurolink-proxy validation" "no 400"
70
+
71
+ echo ""; echo "── 5. Multi-provider sessions ──"
72
+ S=$(curl -s "${A[@]}" "${BASE}/api/sessions")
73
+ NPROV=$(echo "$S" | python3 -c "import json,sys;from collections import Counter;d=json.load(sys.stdin);print(len(Counter(x['source'] for p in d.get('projects',[]) for x in p.get('sessions',[]))))" 2>/dev/null)
74
+ [ "${NPROV:-0}" -ge 5 ] && ok "/api/sessions lists ${NPROV} providers" || no "/api/sessions providers" "only ${NPROV}"
75
+ echo "$S" | grep -q '"iflow"' && no "iflow removed" "iflow still present" || ok "iflow fully removed from API"
76
+ [ "$(hcode "${A[@]}" "${BASE}/api/sessions/detect")" = 200 ] && ok "/api/sessions/detect (running-process scan) 200" || no "sessions/detect" "not 200"
77
+ # conversation retrieval for a real claude session
78
+ CIDP=$(echo "$S" | python3 -c "import json,sys;d=json.load(sys.stdin);print(next((s['id']+'|'+p['id'] for p in d.get('projects',[]) for s in p.get('sessions',[]) if s['source']=='claude-code' and s.get('messageCount',0)>0),''))" 2>/dev/null)
79
+ CID="${CIDP%%|*}"; CPID="${CIDP##*|}"
80
+ if [ -n "$CID" ]; then
81
+ MC=$(curl -s "${A[@]}" "${BASE}/api/sessions?id=${CID}&project=${CPID}&limit=50" | python3 -c "import json,sys;print(len(json.load(sys.stdin).get('messages',[])))" 2>/dev/null)
82
+ [ "${MC:-0}" -gt 0 ] && ok "/api/sessions?id=&project= returns ${MC} parsed messages" || no "conversation read" "0 messages"
83
+ else no "conversation read" "no claude session found"; fi
84
+ # connect validation (security guards)
85
+ [ "$(hcode "${A[@]}" "${J[@]}" -X POST -d '{"sessionId":"../etc","cwd":"/tmp"}' "${BASE}/api/sessions/connect")" = 400 ] && ok "/api/sessions/connect rejects path-traversal id (400)" || no "connect id guard" "no 400"
86
+ [ "$(hcode "${A[@]}" "${J[@]}" -X POST -d '{"sessionId":"abc","cwd":"/etc"}' "${BASE}/api/sessions/connect")" = 400 ] && ok "/api/sessions/connect rejects cwd outside home (400)" || no "connect cwd guard" "no 400"
87
+
88
+ echo ""; echo "── 6. Terminals: create / list / get / resize / paste / delete ──"
89
+ TA=$(curl -s "${A[@]}" "${J[@]}" -X POST -d "{\"command\":\"bash\",\"cwd\":\"${HOME}\"}" "${BASE}/api/terminals")
90
+ TAID=$(echo "$TA" | python3 -c "import json,sys;print(json.load(sys.stdin).get('id',''))" 2>/dev/null)
91
+ [ -n "$TAID" ] && { TERMS="$TERMS $TAID"; ok "POST /api/terminals creates terminal ($TAID)"; } || no "create terminal" "no id"
92
+ curl -s "${A[@]}" "${BASE}/api/terminals" | grep -q "$TAID" && ok "GET /api/terminals lists it" || no "list terminals" "missing"
93
+ [ "$(hcode "${A[@]}" "${BASE}/api/terminals/${TAID}")" = 200 ] && ok "GET /api/terminals/[id] 200" || no "get terminal" "not 200"
94
+ [ "$(hcode "${A[@]}" "${J[@]}" -X POST -d '{"cols":120,"rows":40}' "${BASE}/api/terminals/${TAID}/resize")" = 200 ] && ok "POST /resize 200" || no "resize" "not 200"
95
+ PNG='iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAQAAAC1HAwCAAAAC0lEQVR42mNk+M9QDwADhgGAWjR9awAAAABJRU5ErkJggg=='
96
+ PI=$(curl -s "${A[@]}" "${J[@]}" -X POST -d "{\"image\":\"data:image/png;base64,${PNG}\"}" "${BASE}/api/terminals/${TAID}/paste-image")
97
+ echo "$PI" | grep -q '"success":true' && ok "POST /paste-image writes image" || no "paste-image" "$PI"
98
+
99
+ echo ""; echo "── 7. Bidirectional permission loop (notify→decide→response→poll) ──"
100
+ RID="e2e-perm-$$"
101
+ P1=$(hcode "${A[@]}" "${J[@]}" -X POST -d "{\"title\":\"Permission\",\"message\":\"Allow Bash?\",\"skipPush\":true,\"waitForResponse\":true,\"data\":{\"requestId\":\"${RID}\",\"toolName\":\"Bash\",\"toolInput\":{\"command\":\"ls -la\"}}}" "${BASE}/api/notify")
102
+ [ "$P1" = 200 ] && ok "notify(skipPush+waitForResponse) registers pending request" || no "notify pending" "got $P1"
103
+ DEC=$(curl -s "${A[@]}" "${BASE}/api/decide/${RID}")
104
+ echo "$DEC" | grep -q '"toolName": *"Bash"' && ok "GET /api/decide/[id] returns rich request (toolName/toolInput)" || no "decide payload" "$DEC"
105
+ RC=$(hcode "${A[@]}" "${J[@]}" -X POST -d "{\"requestId\":\"${RID}\",\"decision\":\"allow\"}" "${BASE}/api/response")
106
+ [ "$RC" = 200 ] && ok "POST /api/response(allow) accepted" || no "response post" "got $RC"
107
+ POLL=$(curl -s "${A[@]}" "${BASE}/api/response?requestId=${RID}")
108
+ echo "$POLL" | grep -q '"decision":"allow"' && ok "GET /api/response?requestId= returns the decision (hook unblocks)" || no "response poll" "$POLL"
109
+ RC404=$(hcode "${A[@]}" "${J[@]}" -X POST -d '{"requestId":"nope-xyz","decision":"allow"}' "${BASE}/api/response")
110
+ [ "$RC404" = 404 ] && ok "response on unknown id → 404" || no "response 404" "got $RC404"
111
+
112
+ echo ""; echo "── 8. WebSocket channels (ticket, terminal I/O, session, events) ──"
113
+ cat > "$WSJS" <<JS
114
+ import { WebSocket } from 'ws';
115
+ const BASE='${BASE}', WS='ws://localhost:${PORT}', KEY='${API_KEY}', TID='${TAID}', CID='${CID}';
116
+ const out=(n,p,d='')=>console.log('WS '+n+' '+(p?'PASS':'FAIL')+(d?' | '+d:''));
117
+ const ticket=async()=>{const r=await fetch(BASE+'/api/ws-ticket',{method:'POST',headers:{Authorization:'Bearer '+KEY}});return (await r.json()).ticket;};
118
+ const conn=(path,t)=>new Promise((res,rej)=>{const w=new WebSocket(WS+path+'?ticket='+t);w.once('open',()=>res(w));w.once('error',rej);setTimeout(()=>rej(new Error('timeout '+path)),6000);});
119
+ const collect=(w,ms)=>{const f=[];return new Promise(r=>{const t=setTimeout(()=>r(f),ms);w.on('message',m=>{try{f.push(JSON.parse(m.toString()))}catch{}});});};
120
+ const strip=s=>s.replace(/\x1b\[[0-9;?]*[A-Za-z]/g,'').replace(/\r/g,'');
121
+ try{
122
+ const t1=await ticket(); out('ticket', !!t1, t1?'got ticket':'no ticket');
123
+ // terminal I/O
124
+ const wsT=await conn('/ws/terminal/'+TID,await ticket()); await collect(wsT,800);
125
+ const tok='WS_IO_'+Date.now(); wsT.send(JSON.stringify({type:'input',data:'echo '+tok+'\n'}));
126
+ const fr=await collect(wsT,2500); const o=fr.filter(f=>f.type==='output').map(f=>strip(f.data)).join('');
127
+ out('terminal-io', o.includes(tok), 'echoed token seen='+o.includes(tok));
128
+ wsT.send(JSON.stringify({type:'resize',cols:100,rows:30}));
129
+ const fr2=await collect(wsT,800); out('terminal-resize', wsT.readyState===1, 'socket alive after resize');
130
+ wsT.close();
131
+ // session channel (claude history)
132
+ if(CID){ const wsS=await conn('/ws/session/'+CID,await ticket()); wsS.send(JSON.stringify({type:'subscribe',sessionId:CID}));
133
+ const fs=await collect(wsS,3000); const h=fs.find(f=>f.type==='history');
134
+ out('session-history', !!h && (h.messages||[]).length>0, 'history msgs='+((h&&h.messages||[]).length)); wsS.close(); }
135
+ else out('session-history', false, 'no claude id');
136
+ // events channel: connect then trigger a notify broadcast
137
+ const wsE=await conn('/ws/events',await ticket());
138
+ const ev=collect(wsE,3000);
139
+ await fetch(BASE+'/api/notify',{method:'POST',headers:{Authorization:'Bearer '+KEY,'Content-Type':'application/json'},body:JSON.stringify({title:'EvtPing',message:'evt',eventType:'tool.before',data:{toolName:'Bash',command:'ls'}})});
140
+ const evs=await ev; out('events-broadcast', evs.length>0, 'frames='+evs.length); wsE.close();
141
+ }catch(e){ out('ws-suite', false, e.message); }
142
+ JS
143
+ node "$WSJS" 2>&1 | while read -r line; do
144
+ name=$(echo "$line"|awk '{print $2}'); res=$(echo "$line"|awk '{print $3}'); det=$(echo "$line"|cut -d'|' -f2-)
145
+ [ "$res" = PASS ] && ok "WS ${name}:${det}" || no "WS ${name}" "${det}"
146
+ done
147
+
148
+ echo ""; echo "── 9. Terminal persistence across server restart ──"
149
+ TB=$(curl -s "${A[@]}" "${J[@]}" -X POST -d "{\"command\":\"bash\",\"cwd\":\"${HOME}\"}" "${BASE}/api/terminals")
150
+ TBID=$(echo "$TB" | python3 -c "import json,sys;print(json.load(sys.stdin).get('id',''))" 2>/dev/null)
151
+ [ -n "$TBID" ] && TERMS="$TERMS $TBID"
152
+ HPID=$(pgrep -f "pty-holder.cjs ${TBID}" | head -1)
153
+ [ -n "$HPID" ] && ok "persistence: detached pty-holder process exists (pid $HPID)" || no "holder process" "none for $TBID"
154
+ # restart server
155
+ lsof -ti "tcp:${PORT}" | xargs kill -9 2>/dev/null || true; sleep 2
156
+ start_server; ensure_up || no "restart" "server did not come back"
157
+ sleep 2
158
+ curl -s "${A[@]}" "${BASE}/api/terminals" | grep -q "$TBID" && ok "persistence: terminal survived restart (reconnected from holder)" || no "persistence reconnect" "$TBID gone after restart"
159
+ # holder still alive?
160
+ pgrep -f "pty-holder.cjs ${TBID}" >/dev/null && ok "persistence: same holder process still owns the PTY" || no "holder survived" "holder died"
161
+
162
+ echo ""; echo "════════════════════════════════════════════"
163
+ echo " RESULT: ${PASS} passed, ${FAIL} failed"
164
+ echo "════════════════════════════════════════════"
165
+ [ "$FAIL" -eq 0 ]
@@ -0,0 +1,168 @@
1
+ #!/usr/bin/env bash
2
+ # Shooter cross-terminal E2E smoke test
3
+ # Usage: API_KEY=<key> PORT=54818 bash scripts/e2e-cross-terminal.sh
4
+ # Pre-requisites: build/handler.js must exist (run pnpm build first)
5
+ # Required env: API_KEY (default: e2e-test-key), PORT (default: 54818)
6
+ #
7
+ # Boots the real server and exercises the live HTTP + WebSocket + PTY stack for
8
+ # two independent terminals (A and B), then tears everything down (including the
9
+ # intentionally-detached pty-holder processes). Exits non-zero on any failure.
10
+ # NOTE: this smoke test verifies each terminal's own I/O, not A->coordinator->B
11
+ # relay routing — relay is covered by the SoS suite.
12
+
13
+ set -euo pipefail
14
+
15
+ PORT="${PORT:-54818}"
16
+ API_KEY="${API_KEY:-e2e-test-key}"
17
+ BASE="http://localhost:${PORT}"
18
+ HOME_DIR="${HOME}"
19
+ LOG="/tmp/shooter-e2e-$$.log"
20
+ # Keep the WS client INSIDE the project dir so Node resolves the local `ws` package.
21
+ WS_SCRIPT="$(pwd)/.shooter-e2e-ws-$$.mjs"
22
+ TERM_A_ID=""
23
+ TERM_B_ID=""
24
+ SERVER_PID=""
25
+
26
+ cleanup() {
27
+ [ -n "${TERM_A_ID:-}" ] && curl -s -X DELETE -H "Authorization: Bearer ${API_KEY}" "${BASE}/api/terminals/${TERM_A_ID}" > /dev/null || true
28
+ [ -n "${TERM_B_ID:-}" ] && curl -s -X DELETE -H "Authorization: Bearer ${API_KEY}" "${BASE}/api/terminals/${TERM_B_ID}" > /dev/null || true
29
+ # Terminate the server we started by its own PID; fall back to a port sweep only
30
+ # if we never captured it (avoids killing an unrelated process on this port).
31
+ if [ -n "${SERVER_PID:-}" ]; then
32
+ kill "${SERVER_PID}" 2>/dev/null || true
33
+ else
34
+ lsof -ti "tcp:${PORT}" | xargs kill -9 2>/dev/null || true
35
+ fi
36
+ [ -n "${TERM_A_ID:-}" ] && pkill -f "pty-holder.cjs ${TERM_A_ID}" 2>/dev/null || true
37
+ [ -n "${TERM_B_ID:-}" ] && pkill -f "pty-holder.cjs ${TERM_B_ID}" 2>/dev/null || true
38
+ [ -n "${TERM_A_ID:-}" ] && rm -f "/tmp/shooter-term-${TERM_A_ID}.sock" || true
39
+ [ -n "${TERM_B_ID:-}" ] && rm -f "/tmp/shooter-term-${TERM_B_ID}.sock" || true
40
+ rm -f "${LOG}" "${WS_SCRIPT}"
41
+ echo "TEARDOWN_COMPLETE"
42
+ }
43
+ trap cleanup EXIT
44
+
45
+ echo "=== Shooter Cross-Terminal E2E (port=${PORT}) ==="
46
+
47
+ # 0. Verify build
48
+ [ -f "build/handler.js" ] || { echo "ERROR: build/handler.js not found. Run pnpm build first."; exit 1; }
49
+
50
+ # 1. Start server
51
+ API_KEY="${API_KEY}" PORT="${PORT}" npx tsx server.ts > "${LOG}" 2>&1 &
52
+ SERVER_PID=$!
53
+ echo "Server PID: ${SERVER_PID}"
54
+
55
+ # 2. Wait for health
56
+ echo "Waiting for server..."
57
+ for i in $(seq 1 15); do
58
+ STATUS=$(curl -s -o /dev/null -w "%{http_code}" -H "Authorization: Bearer ${API_KEY}" "${BASE}/api/health" 2>/dev/null || true)
59
+ [ "${STATUS}" = "200" ] && { echo "Server up after $((i*2))s"; break; }
60
+ sleep 2
61
+ done
62
+
63
+ # A: Health
64
+ echo ""; echo "=== A: Health ==="
65
+ HEALTH=$(curl -s -H "Authorization: Bearer ${API_KEY}" "${BASE}/api/health")
66
+ echo "${HEALTH}"
67
+ echo "${HEALTH}" | python3 -c "import json,sys; d=json.load(sys.stdin); assert d['status']=='healthy', d"
68
+ echo "PASS: health=healthy"
69
+
70
+ # B: Sessions
71
+ echo ""; echo "=== B: Sessions ==="
72
+ SESSIONS=$(curl -s -H "Authorization: Bearer ${API_KEY}" "${BASE}/api/sessions")
73
+ COUNT=$(echo "${SESSIONS}" | python3 -c "import json,sys; print(json.load(sys.stdin)['count'])")
74
+ echo "Sessions: ${COUNT}"
75
+ [ "${COUNT}" -gt 0 ] && echo "PASS: count=${COUNT}" || echo "WARN: 0 sessions"
76
+
77
+ # C: Detect
78
+ echo ""; echo "=== C: Detect ==="
79
+ DETECT_STATUS=$(curl -s -o /dev/null -w "%{http_code}" -H "Authorization: Bearer ${API_KEY}" "${BASE}/api/sessions/detect")
80
+ [ "${DETECT_STATUS}" = "200" ] && echo "PASS: detect=200" || { echo "FAIL: detect=${DETECT_STATUS}"; exit 1; }
81
+
82
+ # D: Create terminals
83
+ echo ""; echo "=== D: Create terminals ==="
84
+ TERM_A=$(curl -s -X POST -H "Authorization: Bearer ${API_KEY}" -H "Content-Type: application/json" \
85
+ -d "{\"command\":\"bash\",\"cwd\":\"${HOME_DIR}\"}" "${BASE}/api/terminals")
86
+ TERM_A_ID=$(echo "${TERM_A}" | python3 -c "import json,sys; print(json.load(sys.stdin)['id'])")
87
+ echo "Terminal A: id=${TERM_A_ID}"
88
+
89
+ TERM_B=$(curl -s -X POST -H "Authorization: Bearer ${API_KEY}" -H "Content-Type: application/json" \
90
+ -d "{\"command\":\"bash\",\"cwd\":\"${HOME_DIR}\"}" "${BASE}/api/terminals")
91
+ TERM_B_ID=$(echo "${TERM_B}" | python3 -c "import json,sys; print(json.load(sys.stdin)['id'])")
92
+ echo "Terminal B: id=${TERM_B_ID}"
93
+
94
+ # E/F/G: WebSocket checks via temp .mjs file
95
+ cat > "${WS_SCRIPT}" << JSEOF
96
+ import { WebSocket } from 'ws';
97
+
98
+ const BASE_URL = '${BASE}';
99
+ const WS_BASE = 'ws://localhost:${PORT}';
100
+ const API_KEY = '${API_KEY}';
101
+ const TERM_A = '${TERM_A_ID}';
102
+ const TERM_B = '${TERM_B_ID}';
103
+ const PING = 'PING_FROM_A_' + Date.now();
104
+
105
+ async function getTicket() {
106
+ const r = await fetch(\`\${BASE_URL}/api/ws-ticket\`, { method: 'POST', headers: { Authorization: \`Bearer \${API_KEY}\` } });
107
+ if (!r.ok) throw new Error('ticket failed: ' + r.status);
108
+ return (await r.json()).ticket;
109
+ }
110
+ function connectWs(path, ticket) {
111
+ return new Promise((res, rej) => {
112
+ const ws = new WebSocket(\`\${WS_BASE}\${path}?ticket=\${ticket}\`);
113
+ ws.once('open', () => res(ws));
114
+ ws.once('error', rej);
115
+ setTimeout(() => rej(new Error('timeout ' + path)), 6000);
116
+ });
117
+ }
118
+ function collect(ws, ms) {
119
+ const frames = [];
120
+ return new Promise(res => {
121
+ const t = setTimeout(() => res(frames), ms);
122
+ ws.on('message', raw => { try { frames.push(JSON.parse(raw.toString('utf-8'))); } catch {} });
123
+ ws.once('close', () => { clearTimeout(t); res(frames); });
124
+ });
125
+ }
126
+ const strip = s => s.replace(/\x1b\[[0-9;]*[A-Za-z]/g, '').replace(/\r/g, '');
127
+
128
+ // E: terminal A input -> output
129
+ const tA = await getTicket();
130
+ const wsA = await connectWs('/ws/terminal/' + TERM_A, tA);
131
+ await collect(wsA, 1000);
132
+ wsA.send(JSON.stringify({ type: 'input', data: 'echo ' + PING + '\n' }));
133
+ const frA = await collect(wsA, 3000);
134
+ const outA = frA.filter(f => f.type === 'output').map(f => strip(f.data)).join('');
135
+ const pingLine = outA.split('\n').find(l => l.includes(PING));
136
+ console.log('E PASS:', !!pingLine, '| token:', JSON.stringify(pingLine));
137
+ if (!pingLine) process.exit(1);
138
+
139
+ // F: terminal B independent I/O — write directly to B and verify its echo.
140
+ // NOTE: NOT a relay assertion (A's output is not routed to B here); true
141
+ // A->coordinator->B relay is covered by the SoS suite, not this smoke test.
142
+ const tB = await getTicket();
143
+ const wsB = await connectWs('/ws/terminal/' + TERM_B, tB);
144
+ await collect(wsB, 1000);
145
+ wsB.send(JSON.stringify({ type: 'input', data: 'echo TERMB_IO_' + PING + '\n' }));
146
+ const frB = await collect(wsB, 3000);
147
+ const outB = frB.filter(f => f.type === 'output').map(f => strip(f.data)).join('');
148
+ const ioLine = outB.split('\n').find(l => l.includes('TERMB_IO_'));
149
+ console.log('F PASS (terminal-B I/O, not relay):', !!ioLine, '| token:', JSON.stringify(ioLine));
150
+ if (!ioLine) process.exit(1);
151
+
152
+ // G: /ws/session plain shell -> empty history frame
153
+ const tS = await getTicket();
154
+ const wsS = await connectWs('/ws/session/' + TERM_A, tS);
155
+ const frS = await collect(wsS, 2500);
156
+ wsS.close();
157
+ const hist = frS.find(f => f.type === 'history');
158
+ console.log('G PASS:', !!hist, '| messages:', hist?.messages?.length ?? 'n/a');
159
+ if (!hist) process.exit(1);
160
+
161
+ wsA.close(); wsB.close();
162
+ console.log('ALL_WS_CHECKS: PASS');
163
+ JSEOF
164
+
165
+ echo ""; echo "=== E/F/G: WebSocket checks ==="
166
+ node "${WS_SCRIPT}"
167
+
168
+ echo ""; echo "=== Shooter Cross-Terminal E2E: ALL PASS ==="
package/server.ts CHANGED
@@ -23,7 +23,9 @@ if (!existsSync(handlerPath)) {
23
23
  }
24
24
 
25
25
  const { handler } = await import('./build/handler.js');
26
+ import { isReadOnlyProviderPath } from './src/lib/modules/server/sessions/provider-paths.js';
26
27
  import { codexWatcher } from './src/lib/modules/server/terminal/codex-watcher.js';
28
+ import { genericSessionWatcher } from './src/lib/modules/server/terminal/generic-session-watcher.js';
27
29
  import { openCodeWatcher } from './src/lib/modules/server/terminal/opencode-watcher.js';
28
30
  import { ptyManager } from './src/lib/modules/server/terminal/pty-manager.js';
29
31
  import { sessionWatcher } from './src/lib/modules/server/terminal/session-watcher.js';
@@ -74,6 +76,12 @@ const sessionWatcherAdapter = {
74
76
  if (sessionFile.includes('/.codex/')) {
75
77
  return codexWatcher.getHistory(sessionFile);
76
78
  }
79
+ // Read-only providers (cursor/copilot/qwen/gemini/amp) are re-read whole
80
+ // by the generic watcher — checked before the claude fallback because
81
+ // their JSONL paths would otherwise be mis-parsed as Claude JSONL.
82
+ if (isReadOnlyProviderPath(sessionFile)) {
83
+ return genericSessionWatcher.getHistory(sessionFile);
84
+ }
77
85
  return sessionWatcher.getHistory(sessionFile);
78
86
  },
79
87
  subscribe(sessionFile: string, callback: Parameters<typeof sessionWatcher.watch>[1]) {
@@ -88,6 +96,9 @@ const sessionWatcherAdapter = {
88
96
  callback as (messages: ConversationMessage[]) => void
89
97
  );
90
98
  }
99
+ if (isReadOnlyProviderPath(sessionFile)) {
100
+ return genericSessionWatcher.subscribe(sessionFile, callback);
101
+ }
91
102
  // Use subscribe() which returns a ref-counted unsubscribe function.
92
103
  // The watcher is only torn down when the last subscriber disconnects.
93
104
  return sessionWatcher.subscribe(sessionFile, callback);
@@ -221,6 +232,7 @@ function shutdown(signal: string): void {
221
232
  sessionWatcher.stopAll();
222
233
  openCodeWatcher.stopAll();
223
234
  codexWatcher.stopAll();
235
+ genericSessionWatcher.stopAll();
224
236
 
225
237
  // Terminate all remaining WebSocket clients (/ws/session, /ws/events)
226
238
  // so wss.close() doesn't hang waiting for them to disconnect.
@@ -4,6 +4,6 @@ export { getApiKey, isShooterConfig } from './config-guard';
4
4
  export { toErrorMessage } from './error';
5
5
  export { renderMarkdown } from './markdown';
6
6
  export { hasScanner, isNativeBridge, scanQR } from './native-bridge';
7
- export { sourceLabel, sourceToCommand } from './provider';
7
+ export { AI_COMMANDS, sourceLabel, sourceToCommand } from './provider';
8
8
  export { formatRelativeTime } from './time';
9
9
  export { getToolDescription } from './tool-title';
@@ -6,19 +6,30 @@
6
6
  import type { SessionSource } from '$lib/types';
7
7
 
8
8
  const SOURCE_COMMAND: Record<SessionSource, string> = {
9
+ amp: 'amp',
9
10
  'claude-code': 'claude',
10
11
  codex: 'codex',
12
+ copilot: 'copilot',
13
+ cursor: 'cursor-agent',
11
14
  gemini: 'gemini',
12
15
  opencode: 'opencode',
16
+ qwen: 'qwen',
13
17
  };
14
18
 
15
19
  const SOURCE_LABEL: Record<SessionSource, string> = {
20
+ amp: 'Amp',
16
21
  'claude-code': 'Claude Code',
17
22
  codex: 'Codex',
23
+ copilot: 'Copilot',
24
+ cursor: 'Cursor',
18
25
  gemini: 'Gemini',
19
26
  opencode: 'OpenCode',
27
+ qwen: 'Qwen',
20
28
  };
21
29
 
30
+ /** Every AI-agent CLI binary name (all SessionSources are AI agents, not shells). */
31
+ export const AI_COMMANDS: string[] = Object.values(SOURCE_COMMAND);
32
+
22
33
  /** Human-readable label for a session source. */
23
34
  export function sourceLabel(source: SessionSource): string {
24
35
  return SOURCE_LABEL[source] ?? 'Claude Code';