@dyyz1993/agent-browser 0.28.0 → 0.29.1

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 (209) hide show
  1. package/dist/actions/context.d.ts +4 -0
  2. package/dist/actions/context.d.ts.map +1 -1
  3. package/dist/actions/context.js +41 -1
  4. package/dist/actions/context.js.map +1 -1
  5. package/dist/actions/index.d.ts.map +1 -1
  6. package/dist/actions/index.js +164 -297
  7. package/dist/actions/index.js.map +1 -1
  8. package/dist/actions/interaction.d.ts.map +1 -1
  9. package/dist/actions/interaction.js +96 -30
  10. package/dist/actions/interaction.js.map +1 -1
  11. package/dist/actions/touch.d.ts +25 -0
  12. package/dist/actions/touch.d.ts.map +1 -0
  13. package/dist/actions/touch.js +114 -0
  14. package/dist/actions/touch.js.map +1 -0
  15. package/dist/browser/browser-manager.d.ts +15 -0
  16. package/dist/browser/browser-manager.d.ts.map +1 -1
  17. package/dist/browser/browser-manager.js +75 -7
  18. package/dist/browser/browser-manager.js.map +1 -1
  19. package/dist/browser/network-analysis.d.ts +65 -0
  20. package/dist/browser/network-analysis.d.ts.map +1 -0
  21. package/dist/browser/network-analysis.js +359 -0
  22. package/dist/browser/network-analysis.js.map +1 -0
  23. package/dist/browser/network-tracker.d.ts +4 -0
  24. package/dist/browser/network-tracker.d.ts.map +1 -1
  25. package/dist/browser/network-tracker.js +41 -0
  26. package/dist/browser/network-tracker.js.map +1 -1
  27. package/dist/browser/popup-detector.d.ts +22 -0
  28. package/dist/browser/popup-detector.d.ts.map +1 -0
  29. package/dist/browser/popup-detector.js +138 -0
  30. package/dist/browser/popup-detector.js.map +1 -0
  31. package/dist/cli/commands/index.d.ts +5 -0
  32. package/dist/cli/commands/index.d.ts.map +1 -0
  33. package/dist/cli/commands/index.js +219 -0
  34. package/dist/cli/commands/index.js.map +1 -0
  35. package/dist/cli/commands/interact.d.ts +7 -0
  36. package/dist/cli/commands/interact.d.ts.map +1 -0
  37. package/dist/cli/commands/interact.js +371 -0
  38. package/dist/cli/commands/interact.js.map +1 -0
  39. package/dist/cli/commands/navigate.d.ts +4 -0
  40. package/dist/cli/commands/navigate.d.ts.map +1 -0
  41. package/dist/cli/commands/navigate.js +46 -0
  42. package/dist/cli/commands/navigate.js.map +1 -0
  43. package/dist/cli/commands/network.d.ts +3 -0
  44. package/dist/cli/commands/network.d.ts.map +1 -0
  45. package/dist/cli/commands/network.js +292 -0
  46. package/dist/cli/commands/network.js.map +1 -0
  47. package/dist/cli/commands/plugin.d.ts +3 -0
  48. package/dist/cli/commands/plugin.d.ts.map +1 -0
  49. package/dist/cli/commands/plugin.js +84 -0
  50. package/dist/cli/commands/plugin.js.map +1 -0
  51. package/dist/cli/commands/query.d.ts +7 -0
  52. package/dist/cli/commands/query.d.ts.map +1 -0
  53. package/dist/cli/commands/query.js +333 -0
  54. package/dist/cli/commands/query.js.map +1 -0
  55. package/dist/cli/commands/session.d.ts +3 -0
  56. package/dist/cli/commands/session.d.ts.map +1 -0
  57. package/dist/cli/commands/session.js +372 -0
  58. package/dist/cli/commands/session.js.map +1 -0
  59. package/dist/cli/commands/shared.d.ts +24 -0
  60. package/dist/cli/commands/shared.d.ts.map +1 -0
  61. package/dist/cli/commands/shared.js +113 -0
  62. package/dist/cli/commands/shared.js.map +1 -0
  63. package/dist/cli/commands.d.ts +1 -7
  64. package/dist/cli/commands.d.ts.map +1 -1
  65. package/dist/cli/commands.js +1 -1684
  66. package/dist/cli/commands.js.map +1 -1
  67. package/dist/cli/connection.d.ts.map +1 -1
  68. package/dist/cli/connection.js +9 -1
  69. package/dist/cli/connection.js.map +1 -1
  70. package/dist/cli/help.d.ts.map +1 -1
  71. package/dist/cli/help.js +1 -24
  72. package/dist/cli/help.js.map +1 -1
  73. package/dist/cli.js +2 -2
  74. package/dist/cli.js.map +1 -1
  75. package/dist/daemon.d.ts.map +1 -1
  76. package/dist/daemon.js +21 -1
  77. package/dist/daemon.js.map +1 -1
  78. package/dist/diff.d.ts +4 -0
  79. package/dist/diff.d.ts.map +1 -1
  80. package/dist/diff.js +16 -0
  81. package/dist/diff.js.map +1 -1
  82. package/dist/flow/exporters/cypress.js +1 -1
  83. package/dist/flow/exporters/cypress.js.map +1 -1
  84. package/dist/flow/exporters/selenium.js +1 -1
  85. package/dist/flow/exporters/selenium.js.map +1 -1
  86. package/dist/openapi.d.ts.map +1 -1
  87. package/dist/openapi.js +2 -1
  88. package/dist/openapi.js.map +1 -1
  89. package/dist/plugins/registry.d.ts.map +1 -1
  90. package/dist/plugins/registry.js +4 -1
  91. package/dist/plugins/registry.js.map +1 -1
  92. package/dist/plugins/types.d.ts +4 -4
  93. package/dist/plugins/types.d.ts.map +1 -1
  94. package/dist/protocol.d.ts.map +1 -1
  95. package/dist/protocol.js +30 -7
  96. package/dist/protocol.js.map +1 -1
  97. package/dist/snapshot/constants.d.ts +6 -0
  98. package/dist/snapshot/constants.d.ts.map +1 -0
  99. package/dist/snapshot/constants.js +77 -0
  100. package/dist/snapshot/constants.js.map +1 -0
  101. package/dist/snapshot/dom-scripts.d.ts +12 -0
  102. package/dist/snapshot/dom-scripts.d.ts.map +1 -0
  103. package/dist/snapshot/dom-scripts.js +438 -0
  104. package/dist/snapshot/dom-scripts.js.map +1 -0
  105. package/dist/snapshot/format.d.ts +13 -0
  106. package/dist/snapshot/format.d.ts.map +1 -0
  107. package/dist/snapshot/format.js +175 -0
  108. package/dist/snapshot/format.js.map +1 -0
  109. package/dist/snapshot/index.d.ts +6 -0
  110. package/dist/snapshot/index.d.ts.map +1 -0
  111. package/dist/snapshot/index.js +5 -0
  112. package/dist/snapshot/index.js.map +1 -0
  113. package/dist/snapshot/refs.d.ts +3 -0
  114. package/dist/snapshot/refs.d.ts.map +1 -0
  115. package/dist/snapshot/refs.js +8 -0
  116. package/dist/snapshot/refs.js.map +1 -0
  117. package/dist/snapshot/selectors.d.ts +17 -0
  118. package/dist/snapshot/selectors.d.ts.map +1 -0
  119. package/dist/snapshot/selectors.js +619 -0
  120. package/dist/snapshot/selectors.js.map +1 -0
  121. package/dist/snapshot/snapshot.d.ts +12 -0
  122. package/dist/snapshot/snapshot.d.ts.map +1 -0
  123. package/dist/snapshot/snapshot.js +104 -0
  124. package/dist/snapshot/snapshot.js.map +1 -0
  125. package/dist/snapshot/types.d.ts +27 -0
  126. package/dist/snapshot/types.d.ts.map +1 -0
  127. package/dist/snapshot/types.js +2 -0
  128. package/dist/snapshot/types.js.map +1 -0
  129. package/dist/snapshot.d.ts +1 -79
  130. package/dist/snapshot.d.ts.map +1 -1
  131. package/dist/snapshot.js +1 -1800
  132. package/dist/snapshot.js.map +1 -1
  133. package/dist/stream/client-state.d.ts +13 -0
  134. package/dist/stream/client-state.d.ts.map +1 -0
  135. package/dist/stream/client-state.js +2 -0
  136. package/dist/stream/client-state.js.map +1 -0
  137. package/dist/stream/element-utils.d.ts +8 -0
  138. package/dist/stream/element-utils.d.ts.map +1 -0
  139. package/dist/stream/element-utils.js +25 -0
  140. package/dist/stream/element-utils.js.map +1 -0
  141. package/dist/stream/frame-processor.d.ts +63 -0
  142. package/dist/stream/frame-processor.d.ts.map +1 -0
  143. package/dist/stream/frame-processor.js +178 -0
  144. package/dist/stream/frame-processor.js.map +1 -0
  145. package/dist/stream/index.d.ts +10 -0
  146. package/dist/stream/index.d.ts.map +1 -0
  147. package/dist/stream/index.js +5 -0
  148. package/dist/stream/index.js.map +1 -0
  149. package/dist/stream/input-handler.d.ts +10 -0
  150. package/dist/stream/input-handler.d.ts.map +1 -0
  151. package/dist/stream/input-handler.js +81 -0
  152. package/dist/stream/input-handler.js.map +1 -0
  153. package/dist/stream/messages.d.ts +144 -0
  154. package/dist/stream/messages.d.ts.map +1 -0
  155. package/dist/stream/messages.js +46 -0
  156. package/dist/stream/messages.js.map +1 -0
  157. package/dist/stream-server-standalone.d.ts +0 -3
  158. package/dist/stream-server-standalone.d.ts.map +1 -1
  159. package/dist/stream-server-standalone.js +22 -82
  160. package/dist/stream-server-standalone.js.map +1 -1
  161. package/dist/stream-server.d.ts +8 -212
  162. package/dist/stream-server.d.ts.map +1 -1
  163. package/dist/stream-server.js +35 -389
  164. package/dist/stream-server.js.map +1 -1
  165. package/dist/types/base.d.ts +11 -0
  166. package/dist/types/base.d.ts.map +1 -0
  167. package/dist/types/base.js +2 -0
  168. package/dist/types/base.js.map +1 -0
  169. package/dist/types/browser.d.ts +26 -0
  170. package/dist/types/browser.d.ts.map +1 -0
  171. package/dist/types/browser.js +2 -0
  172. package/dist/types/browser.js.map +1 -0
  173. package/dist/types/commands.d.ts +768 -0
  174. package/dist/types/commands.d.ts.map +1 -0
  175. package/dist/types/commands.js +2 -0
  176. package/dist/types/commands.js.map +1 -0
  177. package/dist/types/crawl.d.ts +89 -0
  178. package/dist/types/crawl.d.ts.map +1 -0
  179. package/dist/types/crawl.js +2 -0
  180. package/dist/types/crawl.js.map +1 -0
  181. package/dist/types/index.d.ts +9 -0
  182. package/dist/types/index.d.ts.map +1 -0
  183. package/dist/types/index.js +9 -0
  184. package/dist/types/index.js.map +1 -0
  185. package/dist/types/interact.d.ts +61 -0
  186. package/dist/types/interact.d.ts.map +1 -0
  187. package/dist/types/interact.js +2 -0
  188. package/dist/types/interact.js.map +1 -0
  189. package/dist/types/plugins.d.ts +39 -0
  190. package/dist/types/plugins.d.ts.map +1 -0
  191. package/dist/types/plugins.js +2 -0
  192. package/dist/types/plugins.js.map +1 -0
  193. package/dist/types/responses.d.ts +140 -0
  194. package/dist/types/responses.d.ts.map +1 -0
  195. package/dist/types/responses.js +4 -0
  196. package/dist/types/responses.js.map +1 -0
  197. package/dist/types/utils.d.ts +12 -0
  198. package/dist/types/utils.d.ts.map +1 -0
  199. package/dist/types/utils.js +2 -0
  200. package/dist/types/utils.js.map +1 -0
  201. package/dist/types.d.ts +1 -1125
  202. package/dist/types.d.ts.map +1 -1
  203. package/dist/types.js +1 -3
  204. package/dist/types.js.map +1 -1
  205. package/dist/version.d.ts +2 -0
  206. package/dist/version.d.ts.map +1 -0
  207. package/dist/version.js +31 -0
  208. package/dist/version.js.map +1 -0
  209. package/package.json +11 -11
@@ -2,203 +2,16 @@ import * as net from 'net';
2
2
  import * as fs from 'fs';
3
3
  import * as path from 'path';
4
4
  import { WebSocketServer, WebSocket } from 'ws';
5
- import sharp from 'sharp';
6
5
  import { setScreencastFrameCallback, setEventCallbacks } from './browser-events.js';
7
6
  import { executeCommand } from './actions/index.js';
8
7
  import { errorResponse, serializeResponse } from './protocol.js';
9
8
  import { getSocketDir, getSession, getInstanceId } from './daemon.js';
10
- export const STATE_CONFIGS = {
11
- user_interacting: { format: 'jpeg', quality: 80, maxFps: 60, scale: 0.6 },
12
- screen_moving: { format: 'jpeg', quality: 75, maxFps: 8, scale: 0.8 },
13
- static: { format: 'jpeg', quality: 80, maxFps: 2, scale: 1 },
14
- };
15
- export class StreamStateManager {
16
- currentState = 'static';
17
- isUserInteracting = false;
18
- userInteractionTimer = null;
19
- lastFrameTime = 0;
20
- frameInterval = Infinity;
21
- onStateChange = null;
22
- staticTimer = null;
23
- USER_INTERACTION_TIMEOUT_MS = 1000;
24
- SCREEN_MOVING_THRESHOLD_MS = 1000;
25
- STATIC_TIMEOUT_MS = 1500;
26
- setStateChangeCallback(callback) {
27
- this.onStateChange = callback;
28
- }
29
- setState(newState) {
30
- if (newState !== this.currentState) {
31
- const previousState = this.currentState;
32
- this.currentState = newState;
33
- this.onStateChange?.(newState, previousState);
34
- }
35
- }
36
- resetStaticTimer() {
37
- if (this.staticTimer) {
38
- clearTimeout(this.staticTimer);
39
- }
40
- this.staticTimer = setTimeout(() => {
41
- if (!this.isUserInteracting) {
42
- this.setState('static');
43
- }
44
- }, this.STATIC_TIMEOUT_MS);
45
- }
46
- onUserInteraction() {
47
- this.setState('user_interacting');
48
- this.isUserInteracting = true;
49
- this.resetUserInteractionTimeout();
50
- this.resetStaticTimer();
51
- }
52
- resetUserInteractionTimeout() {
53
- if (this.userInteractionTimer) {
54
- clearTimeout(this.userInteractionTimer);
55
- }
56
- this.userInteractionTimer = setTimeout(() => {
57
- this.isUserInteracting = false;
58
- const newState = this.frameInterval < this.SCREEN_MOVING_THRESHOLD_MS ? 'screen_moving' : 'static';
59
- this.setState(newState);
60
- }, this.USER_INTERACTION_TIMEOUT_MS);
61
- }
62
- onFrameReceived() {
63
- const now = Date.now();
64
- this.frameInterval = now - this.lastFrameTime;
65
- this.lastFrameTime = now;
66
- if (!this.isUserInteracting) {
67
- const newState = this.frameInterval < this.SCREEN_MOVING_THRESHOLD_MS ? 'screen_moving' : 'static';
68
- this.setState(newState);
69
- }
70
- this.resetStaticTimer();
71
- }
72
- getConfig() {
73
- return STATE_CONFIGS[this.currentState];
74
- }
75
- getState() {
76
- return this.currentState;
77
- }
78
- getFrameInterval() {
79
- return this.frameInterval;
80
- }
81
- getIsUserInteracting() {
82
- return this.isUserInteracting;
83
- }
84
- }
85
- export class FrameRateController {
86
- lastSentTime = 0;
87
- fpsFrameCount = 0;
88
- fpsLastTime = Date.now();
89
- currentFps = 0;
90
- FPS_CALCULATION_INTERVAL_MS = 1000;
91
- shouldSendFrame(maxFps) {
92
- const now = Date.now();
93
- const minInterval = 1000 / maxFps;
94
- if (now - this.lastSentTime >= minInterval) {
95
- this.lastSentTime = now;
96
- this.fpsFrameCount++;
97
- this.calculateFps();
98
- return true;
99
- }
100
- return false;
101
- }
102
- calculateFps() {
103
- const now = Date.now();
104
- const elapsed = now - this.fpsLastTime;
105
- if (elapsed >= this.FPS_CALCULATION_INTERVAL_MS) {
106
- this.currentFps = Math.round((this.fpsFrameCount * 1000) / elapsed);
107
- this.fpsFrameCount = 0;
108
- this.fpsLastTime = now;
109
- }
110
- }
111
- getCurrentFps() {
112
- return this.currentFps;
113
- }
114
- reset() {
115
- this.lastSentTime = 0;
116
- this.fpsFrameCount = 0;
117
- this.fpsLastTime = Date.now();
118
- this.currentFps = 0;
119
- }
120
- }
121
- export class FrameProcessor {
122
- screencastFormat = 'jpeg';
123
- screencastQuality = 80;
124
- async process(data, config, viewportWidth, viewportHeight, cropConfig) {
125
- const buffer = Buffer.from(data, 'base64');
126
- const needsResize = config.scale < 1 && viewportWidth && viewportHeight;
127
- const needsCrop = !!cropConfig;
128
- const needsReencode = config.format !== this.screencastFormat || config.quality !== this.screencastQuality;
129
- if (!needsResize && !needsCrop && !needsReencode) {
130
- return buffer;
131
- }
132
- let processed = sharp(buffer);
133
- if (cropConfig) {
134
- processed = processed.extract({
135
- left: Math.round(cropConfig.x),
136
- top: Math.round(cropConfig.y),
137
- width: Math.round(cropConfig.width),
138
- height: Math.round(cropConfig.height),
139
- });
140
- }
141
- if (needsResize) {
142
- const newWidth = Math.round((viewportWidth ?? 0) * config.scale);
143
- const newHeight = Math.round((viewportHeight ?? 0) * config.scale);
144
- processed = processed.resize(newWidth, newHeight);
145
- }
146
- if (config.format === 'jpeg') {
147
- processed = processed.jpeg({ quality: config.quality });
148
- }
149
- else {
150
- processed = processed.webp({ quality: config.quality });
151
- }
152
- return processed.toBuffer();
153
- }
154
- }
155
- function isPrivateIP(hostname) {
156
- // IPv4 check
157
- const parts = hostname.split('.').map(Number);
158
- if (parts.length === 4 && parts.every((p) => !isNaN(p))) {
159
- const [a, b] = parts;
160
- if (a === 10)
161
- return true;
162
- if (a === 172 && b >= 16 && b <= 31)
163
- return true;
164
- if (a === 192 && b === 168)
165
- return true;
166
- if (a === 127)
167
- return true;
168
- if (a === 0)
169
- return true;
170
- }
171
- // IPv6 check
172
- const lower = hostname.toLowerCase();
173
- if (lower === '::1' || lower === '[::1]' || lower === '::' || lower === 'localhost')
174
- return true;
175
- if (lower.startsWith('fc') || lower.startsWith('fd') || lower.startsWith('fe80'))
176
- return true;
177
- if (hostname === 'localhost')
178
- return true;
179
- return false;
180
- }
181
- export function isAllowedOrigin(origin) {
182
- // CLI connections (no browser origin) are allowed — CLI clients don't send Origin headers
183
- if (!origin) {
184
- return true;
185
- }
186
- if (origin.startsWith('file://')) {
187
- return true;
188
- }
189
- try {
190
- const url = new URL(origin);
191
- if (isPrivateIP(url.hostname)) {
192
- return true;
193
- }
194
- }
195
- catch {
196
- // Invalid origin URL - reject
197
- }
198
- return false;
199
- }
200
- function isCommandMessage(msg) {
201
- return 'id' in msg && 'action' in msg && !('type' in msg);
9
+ import { getVersion } from './version.js';
10
+ import { StreamStateManager, FrameRateController, FrameProcessor, STATE_CONFIGS, isCommandMessage, isAllowedOrigin, getElementBox, handleInputEvent, } from './stream/index.js';
11
+ export { StreamStateManager, FrameRateController, FrameProcessor, STATE_CONFIGS, isAllowedOrigin };
12
+ const STREAM_SERVER_IPC_FILE = 'stream-server.ipc';
13
+ export function getStreamServerIpcPath() {
14
+ return path.join(getSocketDir(), STREAM_SERVER_IPC_FILE);
202
15
  }
203
16
  export class StreamServer {
204
17
  wss = null;
@@ -332,7 +145,7 @@ export class StreamServer {
332
145
  clientState.elementCheckTimer = setInterval(() => {
333
146
  if (!clientState.selector)
334
147
  return;
335
- this.getElementBox(clientState.selector)
148
+ getElementBox(this.browser, clientState.selector)
336
149
  .then((newBox) => {
337
150
  if (!newBox) {
338
151
  if (clientState.elementBox || !clientState.degraded) {
@@ -418,50 +231,16 @@ export class StreamServer {
418
231
  try {
419
232
  switch (message.type) {
420
233
  case 'input_mouse':
421
- this.stateManager.onUserInteraction();
422
- await this.browser.injectMouseEvent({
423
- type: message.eventType,
424
- x: message.x,
425
- y: message.y,
426
- button: message.button,
427
- clickCount: message.clickCount,
428
- deltaX: message.deltaX,
429
- deltaY: message.deltaY,
430
- modifiers: message.modifiers,
431
- });
432
- break;
433
234
  case 'input_keyboard':
434
- this.stateManager.onUserInteraction();
435
- await this.browser.injectKeyboardEvent({
436
- type: message.eventType,
437
- key: message.key,
438
- code: message.code,
439
- text: message.text,
440
- modifiers: message.modifiers,
441
- });
442
- break;
443
235
  case 'input_touch':
444
- this.stateManager.onUserInteraction();
445
- await this.browser.injectTouchEvent({
446
- type: message.eventType,
447
- touchPoints: message.touchPoints,
448
- modifiers: message.modifiers,
449
- });
450
- break;
451
236
  case 'input_text':
452
- this.stateManager.onUserInteraction();
453
- await this.browser.insertText(message.text);
454
- break;
455
237
  case 'keyboard_down':
456
- this.stateManager.onUserInteraction();
457
- await this.browser.getPage().keyboard.down(message.key);
458
- break;
459
238
  case 'keyboard_up':
460
- await this.browser.getPage().keyboard.up(message.key);
461
- break;
462
239
  case 'keyboard_insert_text':
463
- this.stateManager.onUserInteraction();
464
- await this.browser.getPage().keyboard.insertText(message.text);
240
+ case 'input_fill':
241
+ case 'input_blur_element':
242
+ case 'user_activity':
243
+ await handleInputEvent(message, this.browser, this.stateManager);
465
244
  break;
466
245
  case 'input_focused':
467
246
  case 'input_value':
@@ -477,9 +256,6 @@ export class StreamServer {
477
256
  }
478
257
  }
479
258
  break;
480
- case 'user_activity':
481
- this.stateManager.onUserInteraction();
482
- break;
483
259
  case 'status':
484
260
  const cs = this.clients.get(ws);
485
261
  if (cs?.selector) {
@@ -579,25 +355,26 @@ export class StreamServer {
579
355
  }
580
356
  }
581
357
  }
582
- async getElementBox(selector) {
583
- try {
584
- const page = this.browser.getPage();
585
- const box = await page.evaluate((sel) => {
586
- const el = document.querySelector(sel);
587
- if (!el)
588
- return null;
589
- const rect = el.getBoundingClientRect();
590
- return {
591
- x: rect.x,
592
- y: rect.y,
593
- width: rect.width,
594
- height: rect.height,
595
- };
596
- }, selector);
597
- return box ?? undefined;
358
+ async refreshElementBox(ws, clientState) {
359
+ if (!clientState.selector)
360
+ return;
361
+ const box = await getElementBox(this.browser, clientState.selector);
362
+ if (box) {
363
+ clientState.elementBox = box;
364
+ clientState.degraded = false;
598
365
  }
599
- catch {
600
- return undefined;
366
+ else if (!clientState.degraded) {
367
+ clientState.elementBox = undefined;
368
+ clientState.degraded = true;
369
+ const message = {
370
+ type: 'status',
371
+ connected: true,
372
+ screencasting: this.isScreencasting,
373
+ degraded: true,
374
+ };
375
+ if (ws.readyState === WebSocket.OPEN) {
376
+ ws.send(JSON.stringify(message));
377
+ }
601
378
  }
602
379
  }
603
380
  sendStatus(ws, clientState) {
@@ -620,7 +397,7 @@ export class StreamServer {
620
397
  viewportHeight,
621
398
  fps: this.frameRateController.getCurrentFps(),
622
399
  state: this.stateManager.getState(),
623
- version: process.env.npm_package_version || '0.9.5',
400
+ version: getVersion(),
624
401
  };
625
402
  if (clientState?.elementBox) {
626
403
  message.element = {
@@ -640,28 +417,6 @@ export class StreamServer {
640
417
  ws.send(JSON.stringify(message));
641
418
  }
642
419
  }
643
- async refreshElementBox(ws, clientState) {
644
- if (!clientState.selector)
645
- return;
646
- const box = await this.getElementBox(clientState.selector);
647
- if (box) {
648
- clientState.elementBox = box;
649
- clientState.degraded = false;
650
- }
651
- else if (!clientState.degraded) {
652
- clientState.elementBox = undefined;
653
- clientState.degraded = true;
654
- const message = {
655
- type: 'status',
656
- connected: true,
657
- screencasting: this.isScreencasting,
658
- degraded: true,
659
- };
660
- if (ws.readyState === WebSocket.OPEN) {
661
- ws.send(JSON.stringify(message));
662
- }
663
- }
664
- }
665
420
  sendError(ws, errorMessage) {
666
421
  const message = {
667
422
  type: 'error',
@@ -763,10 +518,6 @@ export class StreamServer {
763
518
  return this.frameRateController;
764
519
  }
765
520
  }
766
- const STREAM_SERVER_IPC_FILE = 'stream-server.ipc';
767
- export function getStreamServerIpcPath() {
768
- return path.join(getSocketDir(), STREAM_SERVER_IPC_FILE);
769
- }
770
521
  export class StreamServerProxy {
771
522
  browser;
772
523
  ipcSocket = null;
@@ -844,13 +595,13 @@ export class StreamServerProxy {
844
595
  const line = buffer.substring(0, newlineIdx);
845
596
  buffer = buffer.substring(newlineIdx + 1);
846
597
  if (line.trim()) {
847
- this.handleMessage(line);
598
+ this.handleIpcMessage(line);
848
599
  }
849
600
  }
850
601
  });
851
602
  });
852
603
  }
853
- handleMessage(line) {
604
+ async handleIpcMessage(line) {
854
605
  try {
855
606
  const message = JSON.parse(line);
856
607
  switch (message.type) {
@@ -864,7 +615,7 @@ export class StreamServerProxy {
864
615
  case 'input_fill':
865
616
  case 'input_blur_element':
866
617
  case 'user_activity':
867
- this.handleInputMessage(message);
618
+ await handleInputEvent(message, this.browser, this.stateManager, this.inputFillDebounceMap, StreamServerProxy.INPUT_FILL_DEBOUNCE_MS);
868
619
  break;
869
620
  case 'client_connected':
870
621
  this.handleClientConnected(message.session);
@@ -874,7 +625,7 @@ export class StreamServerProxy {
874
625
  break;
875
626
  case 'request_element_box':
876
627
  (async () => {
877
- const box = await this.getElementBox(message.selector);
628
+ const box = await getElementBox(this.browser, message.selector);
878
629
  const response = {
879
630
  type: 'selector_element',
880
631
  session: message.session ?? this.session,
@@ -919,86 +670,6 @@ export class StreamServerProxy {
919
670
  console.error('[StreamServerProxy] Failed to stop screencast on client disconnected:', error);
920
671
  }
921
672
  }
922
- async handleInputMessage(message) {
923
- try {
924
- switch (message.type) {
925
- case 'input_mouse':
926
- this.stateManager.onUserInteraction();
927
- await this.browser.injectMouseEvent({
928
- type: message.eventType,
929
- x: message.x,
930
- y: message.y,
931
- button: message.button,
932
- clickCount: message.clickCount,
933
- deltaX: message.deltaX,
934
- deltaY: message.deltaY,
935
- modifiers: message.modifiers,
936
- });
937
- break;
938
- case 'input_keyboard':
939
- this.stateManager.onUserInteraction();
940
- await this.browser.injectKeyboardEvent({
941
- type: message.eventType,
942
- key: message.key,
943
- code: message.code,
944
- text: message.text,
945
- modifiers: message.modifiers,
946
- });
947
- break;
948
- case 'input_touch':
949
- this.stateManager.onUserInteraction();
950
- await this.browser.injectTouchEvent({
951
- type: message.eventType,
952
- touchPoints: message.touchPoints,
953
- modifiers: message.modifiers,
954
- });
955
- break;
956
- case 'input_text':
957
- this.stateManager.onUserInteraction();
958
- await this.browser.insertText(message.text);
959
- break;
960
- case 'keyboard_down':
961
- this.stateManager.onUserInteraction();
962
- await this.browser.getPage().keyboard.down(message.key);
963
- break;
964
- case 'keyboard_up':
965
- await this.browser.getPage().keyboard.up(message.key);
966
- break;
967
- case 'keyboard_insert_text':
968
- this.stateManager.onUserInteraction();
969
- await this.browser.getPage().keyboard.insertText(message.text);
970
- break;
971
- case 'input_fill': {
972
- const sel = message.selector || '';
973
- const txt = message.text || '';
974
- const key = sel || '__global__';
975
- const prev = this.inputFillDebounceMap.get(key);
976
- if (prev)
977
- clearTimeout(prev.timer);
978
- const timer = setTimeout(async () => {
979
- this.inputFillDebounceMap.delete(key);
980
- try {
981
- await this.browser.fillValue(sel, txt);
982
- }
983
- catch (e) {
984
- console.error('[StreamServer] input_fill debounce error:', e.message);
985
- }
986
- }, StreamServerProxy.INPUT_FILL_DEBOUNCE_MS);
987
- this.inputFillDebounceMap.set(key, { timer, text: txt, selector: sel });
988
- break;
989
- }
990
- case 'input_blur_element':
991
- await this.browser.blurElement(message.selector || '');
992
- break;
993
- case 'user_activity':
994
- this.stateManager.onUserInteraction();
995
- break;
996
- }
997
- }
998
- catch (error) {
999
- console.error('[StreamServerProxy] Failed to handle input:', error);
1000
- }
1001
- }
1002
673
  setupFrameCallback() {
1003
674
  setScreencastFrameCallback((frame) => {
1004
675
  this.sendFrame(frame).catch((err) => {
@@ -1058,31 +729,6 @@ export class StreamServerProxy {
1058
729
  elementBox,
1059
730
  });
1060
731
  }
1061
- async getElementBox(selector) {
1062
- try {
1063
- const page = this.browser.getPage();
1064
- if (!page) {
1065
- return undefined;
1066
- }
1067
- const box = await page.evaluate((sel) => {
1068
- const el = document.querySelector(sel);
1069
- if (!el)
1070
- return null;
1071
- const rect = el.getBoundingClientRect();
1072
- return {
1073
- x: rect.x,
1074
- y: rect.y,
1075
- width: rect.width,
1076
- height: rect.height,
1077
- };
1078
- }, selector);
1079
- return box ?? undefined;
1080
- }
1081
- catch (err) {
1082
- console.error('[StreamServerProxy] getElementBox error:', err);
1083
- return undefined;
1084
- }
1085
- }
1086
732
  getDaemonSocketPath() {
1087
733
  const isWindows = process.platform === 'win32';
1088
734
  if (isWindows) {