@dyyz1993/agent-browser 0.9.2

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 (187) hide show
  1. package/LICENSE +202 -0
  2. package/README.md +907 -0
  3. package/bin/agent-browser-darwin-arm64 +0 -0
  4. package/bin/agent-browser.js +120 -0
  5. package/dist/__tests__/e2e/utils/test-helpers.d.ts +5 -0
  6. package/dist/__tests__/e2e/utils/test-helpers.d.ts.map +1 -0
  7. package/dist/__tests__/e2e/utils/test-helpers.js +22 -0
  8. package/dist/__tests__/e2e/utils/test-helpers.js.map +1 -0
  9. package/dist/__tests__/test-iframe.d.ts +2 -0
  10. package/dist/__tests__/test-iframe.d.ts.map +1 -0
  11. package/dist/__tests__/test-iframe.js +52 -0
  12. package/dist/__tests__/test-iframe.js.map +1 -0
  13. package/dist/__tests__/utils/parseCli.d.ts +20 -0
  14. package/dist/__tests__/utils/parseCli.d.ts.map +1 -0
  15. package/dist/__tests__/utils/parseCli.js +1086 -0
  16. package/dist/__tests__/utils/parseCli.js.map +1 -0
  17. package/dist/actions.d.ts +50 -0
  18. package/dist/actions.d.ts.map +1 -0
  19. package/dist/actions.js +2164 -0
  20. package/dist/actions.js.map +1 -0
  21. package/dist/browser.d.ts +556 -0
  22. package/dist/browser.d.ts.map +1 -0
  23. package/dist/browser.js +2599 -0
  24. package/dist/browser.js.map +1 -0
  25. package/dist/cli/commands.d.ts +8 -0
  26. package/dist/cli/commands.d.ts.map +1 -0
  27. package/dist/cli/commands.js +1038 -0
  28. package/dist/cli/commands.js.map +1 -0
  29. package/dist/cli/connection.d.ts +50 -0
  30. package/dist/cli/connection.d.ts.map +1 -0
  31. package/dist/cli/connection.js +595 -0
  32. package/dist/cli/connection.js.map +1 -0
  33. package/dist/cli/flags.d.ts +36 -0
  34. package/dist/cli/flags.d.ts.map +1 -0
  35. package/dist/cli/flags.js +206 -0
  36. package/dist/cli/flags.js.map +1 -0
  37. package/dist/cli/help.d.ts +4 -0
  38. package/dist/cli/help.d.ts.map +1 -0
  39. package/dist/cli/help.js +1024 -0
  40. package/dist/cli/help.js.map +1 -0
  41. package/dist/cli/output.d.ts +14 -0
  42. package/dist/cli/output.d.ts.map +1 -0
  43. package/dist/cli/output.js +456 -0
  44. package/dist/cli/output.js.map +1 -0
  45. package/dist/cli-new.d.ts +3 -0
  46. package/dist/cli-new.d.ts.map +1 -0
  47. package/dist/cli-new.js +308 -0
  48. package/dist/cli-new.js.map +1 -0
  49. package/dist/cli-old.d.ts +3 -0
  50. package/dist/cli-old.d.ts.map +1 -0
  51. package/dist/cli-old.js +1101 -0
  52. package/dist/cli-old.js.map +1 -0
  53. package/dist/cli.d.ts +3 -0
  54. package/dist/cli.d.ts.map +1 -0
  55. package/dist/cli.js +403 -0
  56. package/dist/cli.js.map +1 -0
  57. package/dist/content-detection.d.ts +18 -0
  58. package/dist/content-detection.d.ts.map +1 -0
  59. package/dist/content-detection.js +68 -0
  60. package/dist/content-detection.js.map +1 -0
  61. package/dist/daemon.d.ts +55 -0
  62. package/dist/daemon.d.ts.map +1 -0
  63. package/dist/daemon.js +426 -0
  64. package/dist/daemon.js.map +1 -0
  65. package/dist/diff.d.ts +42 -0
  66. package/dist/diff.d.ts.map +1 -0
  67. package/dist/diff.js +166 -0
  68. package/dist/diff.js.map +1 -0
  69. package/dist/human-mouse.d.ts +31 -0
  70. package/dist/human-mouse.d.ts.map +1 -0
  71. package/dist/human-mouse.js +184 -0
  72. package/dist/human-mouse.js.map +1 -0
  73. package/dist/ios-actions.d.ts +11 -0
  74. package/dist/ios-actions.d.ts.map +1 -0
  75. package/dist/ios-actions.js +228 -0
  76. package/dist/ios-actions.js.map +1 -0
  77. package/dist/ios-manager.d.ts +266 -0
  78. package/dist/ios-manager.d.ts.map +1 -0
  79. package/dist/ios-manager.js +1076 -0
  80. package/dist/ios-manager.js.map +1 -0
  81. package/dist/message-bridge.d.ts +10 -0
  82. package/dist/message-bridge.d.ts.map +1 -0
  83. package/dist/message-bridge.js +60 -0
  84. package/dist/message-bridge.js.map +1 -0
  85. package/dist/protocol.d.ts +26 -0
  86. package/dist/protocol.d.ts.map +1 -0
  87. package/dist/protocol.js +912 -0
  88. package/dist/protocol.js.map +1 -0
  89. package/dist/recorder/binding.d.ts +24 -0
  90. package/dist/recorder/binding.d.ts.map +1 -0
  91. package/dist/recorder/binding.js +215 -0
  92. package/dist/recorder/binding.js.map +1 -0
  93. package/dist/recorder/index.d.ts +4 -0
  94. package/dist/recorder/index.d.ts.map +1 -0
  95. package/dist/recorder/index.js +4 -0
  96. package/dist/recorder/index.js.map +1 -0
  97. package/dist/recorder/inject.js +1913 -0
  98. package/dist/recorder/recorder.d.ts +19 -0
  99. package/dist/recorder/recorder.d.ts.map +1 -0
  100. package/dist/recorder/recorder.js +101 -0
  101. package/dist/recorder/recorder.js.map +1 -0
  102. package/dist/recorder/store.d.ts +22 -0
  103. package/dist/recorder/store.d.ts.map +1 -0
  104. package/dist/recorder/store.js +150 -0
  105. package/dist/recorder/store.js.map +1 -0
  106. package/dist/recorder/types.d.ts +73 -0
  107. package/dist/recorder/types.d.ts.map +1 -0
  108. package/dist/recorder/types.js +5 -0
  109. package/dist/recorder/types.js.map +1 -0
  110. package/dist/snapshot.d.ts +81 -0
  111. package/dist/snapshot.d.ts.map +1 -0
  112. package/dist/snapshot.js +1348 -0
  113. package/dist/snapshot.js.map +1 -0
  114. package/dist/stream-server-standalone.d.ts +38 -0
  115. package/dist/stream-server-standalone.d.ts.map +1 -0
  116. package/dist/stream-server-standalone.js +494 -0
  117. package/dist/stream-server-standalone.js.map +1 -0
  118. package/dist/stream-server.d.ts +214 -0
  119. package/dist/stream-server.d.ts.map +1 -0
  120. package/dist/stream-server.js +811 -0
  121. package/dist/stream-server.js.map +1 -0
  122. package/dist/types.d.ts +914 -0
  123. package/dist/types.d.ts.map +1 -0
  124. package/dist/types.js +4 -0
  125. package/dist/types.js.map +1 -0
  126. package/dist/viewer-html.d.ts +2 -0
  127. package/dist/viewer-html.d.ts.map +1 -0
  128. package/dist/viewer-html.js +185 -0
  129. package/dist/viewer-html.js.map +1 -0
  130. package/dist/viewer-script.d.ts +47 -0
  131. package/dist/viewer-script.d.ts.map +1 -0
  132. package/dist/viewer-script.js +586 -0
  133. package/dist/viewer-script.js.map +1 -0
  134. package/package.json +86 -0
  135. package/scripts/build-all-platforms.sh +68 -0
  136. package/scripts/check-version-sync.js +39 -0
  137. package/scripts/check_goods_container.js +35 -0
  138. package/scripts/check_page_content.js +36 -0
  139. package/scripts/click_applause_rate.js +30 -0
  140. package/scripts/copy-native.js +36 -0
  141. package/scripts/copy-recorder.js +21 -0
  142. package/scripts/e2e-test-recorder.ts +584 -0
  143. package/scripts/explore_jd_page.js +31 -0
  144. package/scripts/extract_all_jd_data.js +80 -0
  145. package/scripts/extract_jd_product_detail.js +62 -0
  146. package/scripts/extract_jd_products_correct_links.js +78 -0
  147. package/scripts/extract_jd_products_final.js +80 -0
  148. package/scripts/extract_jd_reviews.js +48 -0
  149. package/scripts/extract_jd_seafood_final.js +78 -0
  150. package/scripts/extract_multiple_products.js +77 -0
  151. package/scripts/extract_products_no_scroll.js +68 -0
  152. package/scripts/extract_products_simple.js +68 -0
  153. package/scripts/find_applause_rate.js +26 -0
  154. package/scripts/find_jd_links.js +28 -0
  155. package/scripts/find_main_content.js +20 -0
  156. package/scripts/find_product_cards.js +38 -0
  157. package/scripts/find_root_content.js +26 -0
  158. package/scripts/find_unique_products.js +55 -0
  159. package/scripts/get_jd_product_detail.js +16 -0
  160. package/scripts/get_jd_products.js +23 -0
  161. package/scripts/get_jd_seafood_products.js +44 -0
  162. package/scripts/get_product_details_from_images.js +54 -0
  163. package/scripts/postinstall.js +235 -0
  164. package/scripts/scroll_and_get_products.js +47 -0
  165. package/scripts/scroll_deep_and_find.js +45 -0
  166. package/scripts/sync-version.js +69 -0
  167. package/scripts/verify-baidu-enter.ts +116 -0
  168. package/skills/agent-browser/SKILL.md +310 -0
  169. package/skills/agent-browser/references/authentication.md +198 -0
  170. package/skills/agent-browser/references/commands.md +471 -0
  171. package/skills/agent-browser/references/data-extraction.md +377 -0
  172. package/skills/agent-browser/references/proxy-support.md +188 -0
  173. package/skills/agent-browser/references/session-management.md +197 -0
  174. package/skills/agent-browser/references/snapshot-refs.md +379 -0
  175. package/skills/agent-browser/references/video-recording.md +173 -0
  176. package/skills/agent-browser/templates/api-interception.sh +53 -0
  177. package/skills/agent-browser/templates/authenticated-session.sh +97 -0
  178. package/skills/agent-browser/templates/capture-workflow.sh +69 -0
  179. package/skills/agent-browser/templates/data-extraction.sh +210 -0
  180. package/skills/agent-browser/templates/form-automation.sh +62 -0
  181. package/skills/skill-creator/LICENSE.txt +202 -0
  182. package/skills/skill-creator/SKILL.md +356 -0
  183. package/skills/skill-creator/references/output-patterns.md +82 -0
  184. package/skills/skill-creator/references/workflows.md +28 -0
  185. package/skills/skill-creator/scripts/init_skill.py +303 -0
  186. package/skills/skill-creator/scripts/package_skill.py +113 -0
  187. package/skills/skill-creator/scripts/quick_validate.py +95 -0
@@ -0,0 +1,912 @@
1
+ import { z } from 'zod';
2
+ // Base schema for all commands
3
+ const baseCommandSchema = z.object({
4
+ id: z.string(),
5
+ action: z.string(),
6
+ });
7
+ // Human config schema for human-like mouse movement (set via AGENT_BROWSER_HUMAN env)
8
+ const humanConfigSchema = z.object({
9
+ enabled: z.boolean(),
10
+ pathType: z.enum(['bezier', 'arc', 'random', 'linear']),
11
+ });
12
+ // Helper to add inFrame support to element-action schemas
13
+ const withFrame = (schema) => schema.extend({ inFrame: z.string().optional() });
14
+ // Individual action schemas
15
+ const launchSchema = baseCommandSchema.extend({
16
+ action: z.literal('launch'),
17
+ headless: z.boolean().optional(),
18
+ viewport: z
19
+ .object({
20
+ width: z.number().positive(),
21
+ height: z.number().positive(),
22
+ })
23
+ .optional(),
24
+ browser: z.enum(['chromium', 'firefox', 'webkit']).optional(),
25
+ cdpPort: z.number().positive().optional(),
26
+ cdpUrl: z
27
+ .string()
28
+ .url()
29
+ .refine((url) => url.startsWith('ws://') ||
30
+ url.startsWith('wss://') ||
31
+ url.startsWith('http://') ||
32
+ url.startsWith('https://'), { message: 'CDP URL must start with ws://, wss://, http://, or https://' })
33
+ .optional(),
34
+ executablePath: z.string().optional(),
35
+ extensions: z.array(z.string()).optional(),
36
+ headers: z.record(z.string()).optional(),
37
+ proxy: z
38
+ .object({
39
+ server: z.string().min(1),
40
+ bypass: z.string().optional(),
41
+ username: z.string().optional(),
42
+ password: z.string().optional(),
43
+ })
44
+ .optional(),
45
+ args: z.array(z.string()).optional(),
46
+ userAgent: z.string().optional(),
47
+ provider: z.string().optional(),
48
+ ignoreHTTPSErrors: z.boolean().optional(),
49
+ profile: z.string().optional(),
50
+ storageState: z.string().optional(),
51
+ });
52
+ const navigateSchema = baseCommandSchema.extend({
53
+ action: z.literal('navigate'),
54
+ url: z.string().min(1),
55
+ waitUntil: z.enum(['load', 'domcontentloaded', 'networkidle']).optional(),
56
+ headers: z.record(z.string()).optional(),
57
+ });
58
+ const clickSchema = withFrame(baseCommandSchema.extend({
59
+ action: z.literal('click'),
60
+ selector: z.string().min(1),
61
+ button: z.enum(['left', 'right', 'middle']).optional(),
62
+ clickCount: z.number().positive().optional(),
63
+ delay: z.number().nonnegative().optional(),
64
+ diffScope: z.union([z.number(), z.literal('full'), z.string()]).optional(),
65
+ human: humanConfigSchema.optional(),
66
+ }));
67
+ const typeSchema = withFrame(baseCommandSchema.extend({
68
+ action: z.literal('type'),
69
+ selector: z.string().min(1),
70
+ text: z.string(),
71
+ delay: z.number().nonnegative().optional(),
72
+ clear: z.boolean().optional(),
73
+ diffScope: z.union([z.number(), z.literal('full'), z.string()]).optional(),
74
+ human: humanConfigSchema.optional(),
75
+ }));
76
+ const fillSchema = withFrame(baseCommandSchema.extend({
77
+ action: z.literal('fill'),
78
+ selector: z.string().min(1),
79
+ value: z.string(),
80
+ diffScope: z.union([z.number(), z.literal('full'), z.string()]).optional(),
81
+ human: humanConfigSchema.optional(),
82
+ }));
83
+ const checkSchema = withFrame(baseCommandSchema.extend({
84
+ action: z.literal('check'),
85
+ selector: z.string().min(1),
86
+ diffScope: z.union([z.number(), z.literal('full'), z.string()]).optional(),
87
+ }));
88
+ const uncheckSchema = withFrame(baseCommandSchema.extend({
89
+ action: z.literal('uncheck'),
90
+ selector: z.string().min(1),
91
+ diffScope: z.union([z.number(), z.literal('full'), z.string()]).optional(),
92
+ }));
93
+ const uploadSchema = baseCommandSchema.extend({
94
+ action: z.literal('upload'),
95
+ selector: z.string().min(1),
96
+ files: z.union([z.string(), z.array(z.string())]),
97
+ });
98
+ const dblclickSchema = withFrame(baseCommandSchema.extend({
99
+ action: z.literal('dblclick'),
100
+ selector: z.string().min(1),
101
+ diffScope: z.union([z.number(), z.literal('full'), z.string()]).optional(),
102
+ human: humanConfigSchema.optional(),
103
+ }));
104
+ const focusSchema = withFrame(baseCommandSchema.extend({
105
+ action: z.literal('focus'),
106
+ selector: z.string().min(1),
107
+ diffScope: z.union([z.number(), z.literal('full'), z.string()]).optional(),
108
+ }));
109
+ const dragSchema = withFrame(baseCommandSchema.extend({
110
+ action: z.literal('drag'),
111
+ source: z.string().min(1),
112
+ target: z.string().min(1),
113
+ }));
114
+ const frameSchema = baseCommandSchema.extend({
115
+ action: z.literal('frame'),
116
+ selector: z.string().min(1).optional(),
117
+ name: z.string().optional(),
118
+ url: z.string().optional(),
119
+ });
120
+ const mainframeSchema = baseCommandSchema.extend({
121
+ action: z.literal('mainframe'),
122
+ });
123
+ const getByRoleSchema = withFrame(baseCommandSchema.extend({
124
+ action: z.literal('getbyrole'),
125
+ role: z.string().min(1),
126
+ name: z.string().optional(),
127
+ exact: z.boolean().optional(),
128
+ subaction: z.enum(['click', 'fill', 'check', 'hover']),
129
+ value: z.string().optional(),
130
+ }));
131
+ const getByTextSchema = withFrame(baseCommandSchema.extend({
132
+ action: z.literal('getbytext'),
133
+ text: z.string().min(1),
134
+ exact: z.boolean().optional(),
135
+ subaction: z.enum(['click', 'hover']),
136
+ }));
137
+ const getByLabelSchema = withFrame(baseCommandSchema.extend({
138
+ action: z.literal('getbylabel'),
139
+ label: z.string().min(1),
140
+ exact: z.boolean().optional(),
141
+ subaction: z.enum(['click', 'fill', 'check']),
142
+ value: z.string().optional(),
143
+ }));
144
+ const getByPlaceholderSchema = withFrame(baseCommandSchema.extend({
145
+ action: z.literal('getbyplaceholder'),
146
+ placeholder: z.string().min(1),
147
+ exact: z.boolean().optional(),
148
+ subaction: z.enum(['click', 'fill']),
149
+ value: z.string().optional(),
150
+ }));
151
+ const cookiesGetSchema = baseCommandSchema.extend({
152
+ action: z.literal('cookies_get'),
153
+ urls: z.array(z.string()).optional(),
154
+ });
155
+ const cookiesSetSchema = baseCommandSchema.extend({
156
+ action: z.literal('cookies_set'),
157
+ cookies: z.array(z.object({
158
+ name: z.string(),
159
+ value: z.string(),
160
+ url: z.string().optional(),
161
+ domain: z.string().optional(),
162
+ path: z.string().optional(),
163
+ expires: z.number().optional(),
164
+ httpOnly: z.boolean().optional(),
165
+ secure: z.boolean().optional(),
166
+ sameSite: z.enum(['Strict', 'Lax', 'None']).optional(),
167
+ })),
168
+ });
169
+ const cookiesClearSchema = baseCommandSchema.extend({
170
+ action: z.literal('cookies_clear'),
171
+ });
172
+ const storageGetSchema = baseCommandSchema.extend({
173
+ action: z.literal('storage_get'),
174
+ key: z.string().optional(),
175
+ type: z.enum(['local', 'session']),
176
+ });
177
+ const storageSetSchema = baseCommandSchema.extend({
178
+ action: z.literal('storage_set'),
179
+ key: z.string().min(1),
180
+ value: z.string(),
181
+ type: z.enum(['local', 'session']),
182
+ });
183
+ const storageClearSchema = baseCommandSchema.extend({
184
+ action: z.literal('storage_clear'),
185
+ type: z.enum(['local', 'session']),
186
+ });
187
+ const dialogSchema = baseCommandSchema.extend({
188
+ action: z.literal('dialog'),
189
+ response: z.enum(['accept', 'dismiss']),
190
+ promptText: z.string().optional(),
191
+ });
192
+ const pdfSchema = baseCommandSchema.extend({
193
+ action: z.literal('pdf'),
194
+ path: z.string().min(1),
195
+ format: z
196
+ .enum(['Letter', 'Legal', 'Tabloid', 'Ledger', 'A0', 'A1', 'A2', 'A3', 'A4', 'A5', 'A6'])
197
+ .optional(),
198
+ });
199
+ const routeSchema = baseCommandSchema.extend({
200
+ action: z.literal('route'),
201
+ url: z.string().min(1),
202
+ response: z
203
+ .object({
204
+ status: z.number().optional(),
205
+ body: z.string().optional(),
206
+ contentType: z.string().optional(),
207
+ headers: z.record(z.string()).optional(),
208
+ })
209
+ .optional(),
210
+ abort: z.boolean().optional(),
211
+ });
212
+ const unrouteSchema = baseCommandSchema.extend({
213
+ action: z.literal('unroute'),
214
+ url: z.string().optional(),
215
+ });
216
+ const requestsSchema = baseCommandSchema.extend({
217
+ action: z.literal('requests'),
218
+ filter: z.string().optional(),
219
+ clear: z.boolean().optional(),
220
+ });
221
+ const downloadSchema = baseCommandSchema.extend({
222
+ action: z.literal('download'),
223
+ selector: z.string().min(1),
224
+ path: z.string().min(1),
225
+ });
226
+ const geolocationSchema = baseCommandSchema.extend({
227
+ action: z.literal('geolocation'),
228
+ latitude: z.number(),
229
+ longitude: z.number(),
230
+ accuracy: z.number().optional(),
231
+ });
232
+ const permissionsSchema = baseCommandSchema.extend({
233
+ action: z.literal('permissions'),
234
+ permissions: z.array(z.string()),
235
+ grant: z.boolean(),
236
+ });
237
+ const viewportSchema = baseCommandSchema.extend({
238
+ action: z.literal('viewport'),
239
+ width: z.number().positive(),
240
+ height: z.number().positive(),
241
+ });
242
+ const userAgentSchema = baseCommandSchema.extend({
243
+ action: z.literal('useragent'),
244
+ userAgent: z.string().min(1),
245
+ });
246
+ const deviceSchema = baseCommandSchema.extend({
247
+ action: z.literal('device'),
248
+ device: z.string().min(1),
249
+ });
250
+ const backSchema = baseCommandSchema.extend({
251
+ action: z.literal('back'),
252
+ });
253
+ const forwardSchema = baseCommandSchema.extend({
254
+ action: z.literal('forward'),
255
+ });
256
+ const reloadSchema = baseCommandSchema.extend({
257
+ action: z.literal('reload'),
258
+ });
259
+ const urlSchema = baseCommandSchema.extend({
260
+ action: z.literal('url'),
261
+ });
262
+ const titleSchema = baseCommandSchema.extend({
263
+ action: z.literal('title'),
264
+ });
265
+ const getAttributeSchema = withFrame(baseCommandSchema.extend({
266
+ action: z.literal('getattribute'),
267
+ selector: z.string().min(1),
268
+ attribute: z.string().min(1),
269
+ }));
270
+ const getTextSchema = withFrame(baseCommandSchema.extend({
271
+ action: z.literal('gettext'),
272
+ selector: z.string().min(1),
273
+ }));
274
+ const isVisibleSchema = withFrame(baseCommandSchema.extend({
275
+ action: z.literal('isvisible'),
276
+ selector: z.string().min(1),
277
+ }));
278
+ const isEnabledSchema = withFrame(baseCommandSchema.extend({
279
+ action: z.literal('isenabled'),
280
+ selector: z.string().min(1),
281
+ }));
282
+ const isCheckedSchema = withFrame(baseCommandSchema.extend({
283
+ action: z.literal('ischecked'),
284
+ selector: z.string().min(1),
285
+ }));
286
+ const countSchema = withFrame(baseCommandSchema.extend({
287
+ action: z.literal('count'),
288
+ selector: z.string().min(1),
289
+ }));
290
+ const boundingBoxSchema = withFrame(baseCommandSchema.extend({
291
+ action: z.literal('boundingbox'),
292
+ selector: z.string().min(1),
293
+ }));
294
+ const stylesSchema = withFrame(baseCommandSchema.extend({
295
+ action: z.literal('styles'),
296
+ selector: z.string().min(1),
297
+ }));
298
+ const videoStartSchema = baseCommandSchema.extend({
299
+ action: z.literal('video_start'),
300
+ path: z.string().min(1),
301
+ });
302
+ const videoStopSchema = baseCommandSchema.extend({
303
+ action: z.literal('video_stop'),
304
+ });
305
+ // Recording schemas (Playwright native video recording)
306
+ const recordingStartSchema = baseCommandSchema.extend({
307
+ action: z.literal('recording_start'),
308
+ path: z.string().min(1),
309
+ url: z.string().min(1).optional(),
310
+ });
311
+ const recordingStopSchema = baseCommandSchema.extend({
312
+ action: z.literal('recording_stop'),
313
+ });
314
+ const recordingRestartSchema = baseCommandSchema.extend({
315
+ action: z.literal('recording_restart'),
316
+ path: z.string().min(1),
317
+ url: z.string().min(1).optional(),
318
+ });
319
+ // Recorder schemas (user interaction recording)
320
+ const recorderStartSchema = baseCommandSchema.extend({
321
+ action: z.literal('recorder_start'),
322
+ url: z.string().min(1).optional(),
323
+ });
324
+ const recorderStopSchema = baseCommandSchema.extend({
325
+ action: z.literal('recorder_stop'),
326
+ output: z.string().min(1).optional(),
327
+ });
328
+ const recorderStatusSchema = baseCommandSchema.extend({
329
+ action: z.literal('recorder_status'),
330
+ });
331
+ const recorderReplaySchema = baseCommandSchema.extend({
332
+ action: z.literal('recorder_replay'),
333
+ path: z.string().optional(),
334
+ });
335
+ const traceStartSchema = baseCommandSchema.extend({
336
+ action: z.literal('trace_start'),
337
+ screenshots: z.boolean().optional(),
338
+ snapshots: z.boolean().optional(),
339
+ });
340
+ const traceStopSchema = baseCommandSchema.extend({
341
+ action: z.literal('trace_stop'),
342
+ path: z.string().min(1),
343
+ });
344
+ const harStartSchema = baseCommandSchema.extend({
345
+ action: z.literal('har_start'),
346
+ });
347
+ const harStopSchema = baseCommandSchema.extend({
348
+ action: z.literal('har_stop'),
349
+ path: z.string().min(1),
350
+ });
351
+ const stateSaveSchema = baseCommandSchema.extend({
352
+ action: z.literal('state_save'),
353
+ path: z.string().min(1),
354
+ });
355
+ const stateLoadSchema = baseCommandSchema.extend({
356
+ action: z.literal('state_load'),
357
+ path: z.string().min(1),
358
+ });
359
+ const consoleSchema = baseCommandSchema.extend({
360
+ action: z.literal('console'),
361
+ clear: z.boolean().optional(),
362
+ });
363
+ const errorsSchema = baseCommandSchema.extend({
364
+ action: z.literal('errors'),
365
+ clear: z.boolean().optional(),
366
+ });
367
+ const keyboardSchema = baseCommandSchema.extend({
368
+ action: z.literal('keyboard'),
369
+ keys: z.string().min(1),
370
+ });
371
+ const wheelSchema = baseCommandSchema.extend({
372
+ action: z.literal('wheel'),
373
+ deltaX: z.number().optional(),
374
+ deltaY: z.number().optional(),
375
+ selector: z.string().optional(),
376
+ });
377
+ const tapSchema = baseCommandSchema.extend({
378
+ action: z.literal('tap'),
379
+ selector: z.string().min(1),
380
+ });
381
+ const clipboardSchema = baseCommandSchema.extend({
382
+ action: z.literal('clipboard'),
383
+ operation: z.enum(['copy', 'paste', 'read']),
384
+ text: z.string().optional(),
385
+ });
386
+ const highlightSchema = withFrame(baseCommandSchema.extend({
387
+ action: z.literal('highlight'),
388
+ selector: z.string().min(1),
389
+ }));
390
+ const clearSchema = withFrame(baseCommandSchema.extend({
391
+ action: z.literal('clear'),
392
+ selector: z.string().min(1),
393
+ }));
394
+ const selectAllSchema = withFrame(baseCommandSchema.extend({
395
+ action: z.literal('selectall'),
396
+ selector: z.string().min(1),
397
+ }));
398
+ const innerTextSchema = withFrame(baseCommandSchema.extend({
399
+ action: z.literal('innertext'),
400
+ selector: z.string().min(1),
401
+ }));
402
+ const innerHtmlSchema = withFrame(baseCommandSchema.extend({
403
+ action: z.literal('innerhtml'),
404
+ selector: z.string().min(1),
405
+ }));
406
+ const inputValueSchema = withFrame(baseCommandSchema.extend({
407
+ action: z.literal('inputvalue'),
408
+ selector: z.string().min(1),
409
+ }));
410
+ const setValueSchema = withFrame(baseCommandSchema.extend({
411
+ action: z.literal('setvalue'),
412
+ selector: z.string().min(1),
413
+ value: z.string(),
414
+ }));
415
+ const dispatchSchema = withFrame(baseCommandSchema.extend({
416
+ action: z.literal('dispatch'),
417
+ selector: z.string().min(1),
418
+ event: z.string().min(1),
419
+ eventInit: z.record(z.unknown()).optional(),
420
+ }));
421
+ const evalHandleSchema = baseCommandSchema.extend({
422
+ action: z.literal('evalhandle'),
423
+ script: z.string().min(1),
424
+ });
425
+ const exposeSchema = baseCommandSchema.extend({
426
+ action: z.literal('expose'),
427
+ name: z.string().min(1),
428
+ });
429
+ const addScriptSchema = baseCommandSchema.extend({
430
+ action: z.literal('addscript'),
431
+ content: z.string().optional(),
432
+ url: z.string().optional(),
433
+ });
434
+ const addStyleSchema = baseCommandSchema.extend({
435
+ action: z.literal('addstyle'),
436
+ content: z.string().optional(),
437
+ url: z.string().optional(),
438
+ });
439
+ const emulateMediaSchema = baseCommandSchema.extend({
440
+ action: z.literal('emulatemedia'),
441
+ media: z.enum(['screen', 'print']).nullable().optional(),
442
+ colorScheme: z.enum(['light', 'dark', 'no-preference']).nullable().optional(),
443
+ reducedMotion: z.enum(['reduce', 'no-preference']).nullable().optional(),
444
+ forcedColors: z.enum(['active', 'none']).nullable().optional(),
445
+ });
446
+ const offlineSchema = baseCommandSchema.extend({
447
+ action: z.literal('offline'),
448
+ offline: z.boolean(),
449
+ });
450
+ const headersSchema = baseCommandSchema.extend({
451
+ action: z.literal('headers'),
452
+ headers: z.record(z.string()),
453
+ });
454
+ const pauseSchema = baseCommandSchema.extend({
455
+ action: z.literal('pause'),
456
+ });
457
+ const getByAltTextSchema = withFrame(baseCommandSchema.extend({
458
+ action: z.literal('getbyalttext'),
459
+ text: z.string().min(1),
460
+ exact: z.boolean().optional(),
461
+ subaction: z.enum(['click', 'hover']),
462
+ }));
463
+ const getByTitleSchema = withFrame(baseCommandSchema.extend({
464
+ action: z.literal('getbytitle'),
465
+ text: z.string().min(1),
466
+ exact: z.boolean().optional(),
467
+ subaction: z.enum(['click', 'hover']),
468
+ }));
469
+ const getByTestIdSchema = withFrame(baseCommandSchema.extend({
470
+ action: z.literal('getbytestid'),
471
+ testId: z.string().min(1),
472
+ subaction: z.enum(['click', 'fill', 'check', 'hover']),
473
+ value: z.string().optional(),
474
+ }));
475
+ const nthSchema = withFrame(baseCommandSchema.extend({
476
+ action: z.literal('nth'),
477
+ selector: z.string().min(1),
478
+ index: z.number(),
479
+ subaction: z.enum(['click', 'fill', 'check', 'hover', 'text']),
480
+ value: z.string().optional(),
481
+ }));
482
+ const waitForUrlSchema = baseCommandSchema.extend({
483
+ action: z.literal('waitforurl'),
484
+ url: z.string().min(1),
485
+ timeout: z.number().positive().optional(),
486
+ });
487
+ const waitForLoadStateSchema = baseCommandSchema.extend({
488
+ action: z.literal('waitforloadstate'),
489
+ state: z.enum(['load', 'domcontentloaded', 'networkidle']),
490
+ timeout: z.number().positive().optional(),
491
+ });
492
+ const setContentSchema = baseCommandSchema.extend({
493
+ action: z.literal('setcontent'),
494
+ html: z.string(),
495
+ });
496
+ const timezoneSchema = baseCommandSchema.extend({
497
+ action: z.literal('timezone'),
498
+ timezone: z.string().min(1),
499
+ });
500
+ const localeSchema = baseCommandSchema.extend({
501
+ action: z.literal('locale'),
502
+ locale: z.string().min(1),
503
+ });
504
+ const credentialsSchema = baseCommandSchema.extend({
505
+ action: z.literal('credentials'),
506
+ username: z.string(),
507
+ password: z.string(),
508
+ });
509
+ const mouseMoveSchema = baseCommandSchema.extend({
510
+ action: z.literal('mousemove'),
511
+ x: z.number(),
512
+ y: z.number(),
513
+ });
514
+ const mouseDownSchema = baseCommandSchema.extend({
515
+ action: z.literal('mousedown'),
516
+ button: z.enum(['left', 'right', 'middle']).optional(),
517
+ });
518
+ const mouseUpSchema = baseCommandSchema.extend({
519
+ action: z.literal('mouseup'),
520
+ button: z.enum(['left', 'right', 'middle']).optional(),
521
+ });
522
+ const wanderSchema = baseCommandSchema.extend({
523
+ action: z.literal('wander'),
524
+ duration: z.number().positive().optional(),
525
+ human: z
526
+ .object({
527
+ enabled: z.boolean(),
528
+ pathType: z.enum(['bezier', 'arc', 'random', 'linear']),
529
+ })
530
+ .optional(),
531
+ });
532
+ const mouseTrajectorySchema = baseCommandSchema.extend({
533
+ action: z.literal('mousetrajectory'),
534
+ data: z.string().min(1),
535
+ human: humanConfigSchema.optional(),
536
+ });
537
+ const bringToFrontSchema = baseCommandSchema.extend({
538
+ action: z.literal('bringtofront'),
539
+ });
540
+ const waitForFunctionSchema = baseCommandSchema.extend({
541
+ action: z.literal('waitforfunction'),
542
+ expression: z.string().min(1),
543
+ timeout: z.number().positive().optional(),
544
+ });
545
+ const scrollIntoViewSchema = withFrame(baseCommandSchema.extend({
546
+ action: z.literal('scrollintoview'),
547
+ selector: z.string().min(1),
548
+ }));
549
+ const addInitScriptSchema = baseCommandSchema.extend({
550
+ action: z.literal('addinitscript'),
551
+ script: z.string().min(1),
552
+ });
553
+ const keyDownSchema = baseCommandSchema.extend({
554
+ action: z.literal('keydown'),
555
+ key: z.string().min(1),
556
+ });
557
+ const keyUpSchema = baseCommandSchema.extend({
558
+ action: z.literal('keyup'),
559
+ key: z.string().min(1),
560
+ });
561
+ const insertTextSchema = baseCommandSchema.extend({
562
+ action: z.literal('inserttext'),
563
+ text: z.string(),
564
+ });
565
+ const multiSelectSchema = baseCommandSchema.extend({
566
+ action: z.literal('multiselect'),
567
+ selector: z.string().min(1),
568
+ values: z.array(z.string()),
569
+ });
570
+ const waitForDownloadSchema = baseCommandSchema.extend({
571
+ action: z.literal('waitfordownload'),
572
+ path: z.string().optional(),
573
+ timeout: z.number().positive().optional(),
574
+ });
575
+ const responseBodySchema = baseCommandSchema.extend({
576
+ action: z.literal('responsebody'),
577
+ url: z.string().min(1),
578
+ timeout: z.number().positive().optional(),
579
+ });
580
+ // Screencast schemas for streaming browser viewport
581
+ const screencastStartSchema = baseCommandSchema.extend({
582
+ action: z.literal('screencast_start'),
583
+ format: z.enum(['jpeg', 'png']).optional(),
584
+ quality: z.number().min(0).max(100).optional(),
585
+ maxWidth: z.number().positive().optional(),
586
+ maxHeight: z.number().positive().optional(),
587
+ everyNthFrame: z.number().positive().optional(),
588
+ });
589
+ const screencastStopSchema = baseCommandSchema.extend({
590
+ action: z.literal('screencast_stop'),
591
+ });
592
+ // Input injection schemas for pair browsing
593
+ const inputMouseSchema = baseCommandSchema.extend({
594
+ action: z.literal('input_mouse'),
595
+ type: z.enum(['mousePressed', 'mouseReleased', 'mouseMoved', 'mouseWheel']),
596
+ x: z.number(),
597
+ y: z.number(),
598
+ button: z.enum(['left', 'right', 'middle', 'none']).optional(),
599
+ clickCount: z.number().positive().optional(),
600
+ deltaX: z.number().optional(),
601
+ deltaY: z.number().optional(),
602
+ modifiers: z.number().optional(),
603
+ });
604
+ const inputKeyboardSchema = baseCommandSchema.extend({
605
+ action: z.literal('input_keyboard'),
606
+ type: z.enum(['keyDown', 'keyUp', 'char']),
607
+ key: z.string().optional(),
608
+ code: z.string().optional(),
609
+ text: z.string().optional(),
610
+ modifiers: z.number().optional(),
611
+ });
612
+ const inputTouchSchema = baseCommandSchema.extend({
613
+ action: z.literal('input_touch'),
614
+ type: z.enum(['touchStart', 'touchEnd', 'touchMove', 'touchCancel']),
615
+ touchPoints: z.array(z.object({
616
+ x: z.number(),
617
+ y: z.number(),
618
+ id: z.number().optional(),
619
+ })),
620
+ modifiers: z.number().optional(),
621
+ });
622
+ // iOS-specific schemas
623
+ const swipeSchema = baseCommandSchema.extend({
624
+ action: z.literal('swipe'),
625
+ direction: z.enum(['up', 'down', 'left', 'right']),
626
+ distance: z.number().positive().optional(),
627
+ });
628
+ const deviceListSchema = baseCommandSchema.extend({
629
+ action: z.literal('device_list'),
630
+ });
631
+ const viewerSchema = baseCommandSchema.extend({
632
+ action: z.literal('viewer'),
633
+ });
634
+ const askSchema = baseCommandSchema.extend({
635
+ action: z.literal('ask'),
636
+ question: z.string().min(1),
637
+ });
638
+ const configSchema = baseCommandSchema.extend({
639
+ action: z.literal('config'),
640
+ json: z.boolean().optional(),
641
+ });
642
+ const pressSchema = baseCommandSchema.extend({
643
+ action: z.literal('press'),
644
+ key: z.string().min(1),
645
+ selector: z.string().min(1).optional(),
646
+ diffScope: z.union([z.number(), z.literal('full'), z.string()]).optional(),
647
+ });
648
+ const screenshotSchema = baseCommandSchema.extend({
649
+ action: z.literal('screenshot'),
650
+ path: z.string().nullable().optional(),
651
+ fullPage: z.boolean().optional(),
652
+ selector: z.string().min(1).nullish(),
653
+ format: z.enum(['png', 'jpeg']).optional(),
654
+ quality: z.number().min(0).max(100).optional(),
655
+ });
656
+ const snapshotSchema = withFrame(baseCommandSchema.extend({
657
+ action: z.literal('snapshot'),
658
+ interactive: z.boolean().optional(),
659
+ maxDepth: z.number().nonnegative().optional(),
660
+ compact: z.boolean().optional(),
661
+ selector: z.string().optional(),
662
+ cursor: z.boolean().optional(),
663
+ path: z.boolean().optional(),
664
+ attrs: z.boolean().optional(),
665
+ }));
666
+ const evaluateSchema = baseCommandSchema.extend({
667
+ action: z.literal('evaluate'),
668
+ script: z.string().min(1).optional(),
669
+ file: z.string().min(1).optional(),
670
+ args: z.array(z.unknown()).optional(),
671
+ });
672
+ const waitSchema = baseCommandSchema.extend({
673
+ action: z.literal('wait'),
674
+ selector: z.string().min(1).optional(),
675
+ timeout: z.number().positive().optional(),
676
+ state: z.enum(['attached', 'detached', 'visible', 'hidden']).optional(),
677
+ });
678
+ const scrollSchema = baseCommandSchema.extend({
679
+ action: z.literal('scroll'),
680
+ selector: z.string().min(1).optional(),
681
+ x: z.number().optional(),
682
+ y: z.number().optional(),
683
+ direction: z.enum(['up', 'down', 'left', 'right']).optional(),
684
+ amount: z.number().positive().optional(),
685
+ });
686
+ const selectSchema = withFrame(baseCommandSchema.extend({
687
+ action: z.literal('select'),
688
+ selector: z.string().min(1),
689
+ values: z.union([z.string(), z.array(z.string())]),
690
+ diffScope: z.union([z.number(), z.literal('full'), z.string()]).optional(),
691
+ }));
692
+ const hoverSchema = withFrame(baseCommandSchema.extend({
693
+ action: z.literal('hover'),
694
+ selector: z.string().min(1),
695
+ diffScope: z.union([z.number(), z.literal('full'), z.string()]).optional(),
696
+ human: humanConfigSchema.optional(),
697
+ }));
698
+ const contentSchema = baseCommandSchema.extend({
699
+ action: z.literal('content'),
700
+ selector: z.string().min(1).optional(),
701
+ });
702
+ const closeSchema = baseCommandSchema.extend({
703
+ action: z.literal('close'),
704
+ });
705
+ // Tab/Window schemas
706
+ const tabNewSchema = baseCommandSchema.extend({
707
+ action: z.literal('tab_new'),
708
+ url: z.string().min(1).optional(),
709
+ });
710
+ const tabListSchema = baseCommandSchema.extend({
711
+ action: z.literal('tab_list'),
712
+ });
713
+ const tabSwitchSchema = baseCommandSchema.extend({
714
+ action: z.literal('tab_switch'),
715
+ index: z.number().nonnegative(),
716
+ });
717
+ const tabCloseSchema = baseCommandSchema.extend({
718
+ action: z.literal('tab_close'),
719
+ index: z.number().nonnegative().optional(),
720
+ });
721
+ const windowNewSchema = baseCommandSchema.extend({
722
+ action: z.literal('window_new'),
723
+ viewport: z
724
+ .object({
725
+ width: z.number().positive(),
726
+ height: z.number().positive(),
727
+ })
728
+ .optional(),
729
+ });
730
+ // Union schema for all commands
731
+ const commandSchema = z.discriminatedUnion('action', [
732
+ launchSchema,
733
+ navigateSchema,
734
+ clickSchema,
735
+ typeSchema,
736
+ fillSchema,
737
+ checkSchema,
738
+ uncheckSchema,
739
+ uploadSchema,
740
+ dblclickSchema,
741
+ focusSchema,
742
+ dragSchema,
743
+ frameSchema,
744
+ mainframeSchema,
745
+ getByRoleSchema,
746
+ getByTextSchema,
747
+ getByLabelSchema,
748
+ getByPlaceholderSchema,
749
+ pressSchema,
750
+ screenshotSchema,
751
+ snapshotSchema,
752
+ evaluateSchema,
753
+ waitSchema,
754
+ scrollSchema,
755
+ selectSchema,
756
+ hoverSchema,
757
+ contentSchema,
758
+ closeSchema,
759
+ tabNewSchema,
760
+ tabListSchema,
761
+ tabSwitchSchema,
762
+ tabCloseSchema,
763
+ windowNewSchema,
764
+ cookiesGetSchema,
765
+ cookiesSetSchema,
766
+ cookiesClearSchema,
767
+ storageGetSchema,
768
+ storageSetSchema,
769
+ storageClearSchema,
770
+ dialogSchema,
771
+ pdfSchema,
772
+ routeSchema,
773
+ unrouteSchema,
774
+ requestsSchema,
775
+ downloadSchema,
776
+ geolocationSchema,
777
+ permissionsSchema,
778
+ viewportSchema,
779
+ userAgentSchema,
780
+ deviceSchema,
781
+ backSchema,
782
+ forwardSchema,
783
+ reloadSchema,
784
+ urlSchema,
785
+ titleSchema,
786
+ getAttributeSchema,
787
+ getTextSchema,
788
+ isVisibleSchema,
789
+ isEnabledSchema,
790
+ isCheckedSchema,
791
+ countSchema,
792
+ boundingBoxSchema,
793
+ stylesSchema,
794
+ videoStartSchema,
795
+ videoStopSchema,
796
+ recordingStartSchema,
797
+ recordingStopSchema,
798
+ recordingRestartSchema,
799
+ recorderStartSchema,
800
+ recorderStopSchema,
801
+ recorderStatusSchema,
802
+ recorderReplaySchema,
803
+ traceStartSchema,
804
+ traceStopSchema,
805
+ harStartSchema,
806
+ harStopSchema,
807
+ stateSaveSchema,
808
+ stateLoadSchema,
809
+ consoleSchema,
810
+ errorsSchema,
811
+ keyboardSchema,
812
+ wheelSchema,
813
+ tapSchema,
814
+ clipboardSchema,
815
+ highlightSchema,
816
+ clearSchema,
817
+ selectAllSchema,
818
+ innerTextSchema,
819
+ innerHtmlSchema,
820
+ inputValueSchema,
821
+ setValueSchema,
822
+ dispatchSchema,
823
+ evalHandleSchema,
824
+ exposeSchema,
825
+ addScriptSchema,
826
+ addStyleSchema,
827
+ emulateMediaSchema,
828
+ offlineSchema,
829
+ headersSchema,
830
+ pauseSchema,
831
+ getByAltTextSchema,
832
+ getByTitleSchema,
833
+ getByTestIdSchema,
834
+ nthSchema,
835
+ waitForUrlSchema,
836
+ waitForLoadStateSchema,
837
+ setContentSchema,
838
+ timezoneSchema,
839
+ localeSchema,
840
+ credentialsSchema,
841
+ mouseMoveSchema,
842
+ mouseDownSchema,
843
+ mouseUpSchema,
844
+ wanderSchema,
845
+ mouseTrajectorySchema,
846
+ bringToFrontSchema,
847
+ waitForFunctionSchema,
848
+ scrollIntoViewSchema,
849
+ addInitScriptSchema,
850
+ keyDownSchema,
851
+ keyUpSchema,
852
+ insertTextSchema,
853
+ multiSelectSchema,
854
+ waitForDownloadSchema,
855
+ responseBodySchema,
856
+ screencastStartSchema,
857
+ screencastStopSchema,
858
+ inputMouseSchema,
859
+ inputKeyboardSchema,
860
+ inputTouchSchema,
861
+ swipeSchema,
862
+ deviceListSchema,
863
+ viewerSchema,
864
+ askSchema,
865
+ configSchema,
866
+ ]);
867
+ /**
868
+ * Parse a JSON string into a validated command
869
+ */
870
+ export function parseCommand(input) {
871
+ // First, try to parse JSON
872
+ let json;
873
+ try {
874
+ json = JSON.parse(input);
875
+ }
876
+ catch {
877
+ return { success: false, error: 'Invalid JSON' };
878
+ }
879
+ // Extract id for error responses if possible
880
+ const id = typeof json === 'object' && json !== null && 'id' in json
881
+ ? String(json.id)
882
+ : undefined;
883
+ // Validate against schema
884
+ const result = commandSchema.safeParse(json);
885
+ if (!result.success) {
886
+ const errors = result.error.errors.map((e) => `${e.path.join('.')}: ${e.message}`).join(', ');
887
+ return { success: false, error: `Validation error: ${errors}`, id };
888
+ }
889
+ return { success: true, command: result.data };
890
+ }
891
+ /**
892
+ * Create a success response
893
+ */
894
+ export function successResponse(id, data, tips) {
895
+ const response = { id, success: true, data };
896
+ if (tips)
897
+ response.tips = tips;
898
+ return response;
899
+ }
900
+ /**
901
+ * Create an error response
902
+ */
903
+ export function errorResponse(id, error) {
904
+ return { id, success: false, error };
905
+ }
906
+ /**
907
+ * Serialize a response to JSON string
908
+ */
909
+ export function serializeResponse(response) {
910
+ return JSON.stringify(response);
911
+ }
912
+ //# sourceMappingURL=protocol.js.map