nstbrowser-ai-agent 0.0.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 (119) hide show
  1. package/LICENSE +201 -0
  2. package/README.md +1321 -0
  3. package/bin/nstbrowser-ai-agent-darwin-arm64 +0 -0
  4. package/bin/nstbrowser-ai-agent-darwin-x64 +0 -0
  5. package/bin/nstbrowser-ai-agent-linux-arm64 +0 -0
  6. package/bin/nstbrowser-ai-agent-linux-x64 +0 -0
  7. package/bin/nstbrowser-ai-agent-win32-x64.exe +0 -0
  8. package/bin/nstbrowser-ai-agent.js +109 -0
  9. package/dist/action-policy.d.ts +14 -0
  10. package/dist/action-policy.d.ts.map +1 -0
  11. package/dist/action-policy.js +253 -0
  12. package/dist/action-policy.js.map +1 -0
  13. package/dist/actions.d.ts +18 -0
  14. package/dist/actions.d.ts.map +1 -0
  15. package/dist/actions.js +2037 -0
  16. package/dist/actions.js.map +1 -0
  17. package/dist/auth-cli.d.ts +2 -0
  18. package/dist/auth-cli.d.ts.map +1 -0
  19. package/dist/auth-cli.js +97 -0
  20. package/dist/auth-cli.js.map +1 -0
  21. package/dist/auth-vault.d.ts +36 -0
  22. package/dist/auth-vault.d.ts.map +1 -0
  23. package/dist/auth-vault.js +125 -0
  24. package/dist/auth-vault.js.map +1 -0
  25. package/dist/browser.d.ts +573 -0
  26. package/dist/browser.d.ts.map +1 -0
  27. package/dist/browser.js +2036 -0
  28. package/dist/browser.js.map +1 -0
  29. package/dist/confirmation.d.ts +8 -0
  30. package/dist/confirmation.d.ts.map +1 -0
  31. package/dist/confirmation.js +30 -0
  32. package/dist/confirmation.js.map +1 -0
  33. package/dist/daemon.d.ts +65 -0
  34. package/dist/daemon.d.ts.map +1 -0
  35. package/dist/daemon.js +589 -0
  36. package/dist/daemon.js.map +1 -0
  37. package/dist/diff.d.ts +18 -0
  38. package/dist/diff.d.ts.map +1 -0
  39. package/dist/diff.js +271 -0
  40. package/dist/diff.js.map +1 -0
  41. package/dist/domain-filter.d.ts +28 -0
  42. package/dist/domain-filter.d.ts.map +1 -0
  43. package/dist/domain-filter.js +149 -0
  44. package/dist/domain-filter.js.map +1 -0
  45. package/dist/encryption.d.ts +73 -0
  46. package/dist/encryption.d.ts.map +1 -0
  47. package/dist/encryption.js +171 -0
  48. package/dist/encryption.js.map +1 -0
  49. package/dist/ios-actions.d.ts +11 -0
  50. package/dist/ios-actions.d.ts.map +1 -0
  51. package/dist/ios-actions.js +228 -0
  52. package/dist/ios-actions.js.map +1 -0
  53. package/dist/ios-manager.d.ts +266 -0
  54. package/dist/ios-manager.d.ts.map +1 -0
  55. package/dist/ios-manager.js +1073 -0
  56. package/dist/ios-manager.js.map +1 -0
  57. package/dist/nstbrowser-actions.d.ts +10 -0
  58. package/dist/nstbrowser-actions.d.ts.map +1 -0
  59. package/dist/nstbrowser-actions.js +277 -0
  60. package/dist/nstbrowser-actions.js.map +1 -0
  61. package/dist/nstbrowser-client.d.ts +197 -0
  62. package/dist/nstbrowser-client.d.ts.map +1 -0
  63. package/dist/nstbrowser-client.js +454 -0
  64. package/dist/nstbrowser-client.js.map +1 -0
  65. package/dist/nstbrowser-errors.d.ts +28 -0
  66. package/dist/nstbrowser-errors.d.ts.map +1 -0
  67. package/dist/nstbrowser-errors.js +59 -0
  68. package/dist/nstbrowser-errors.js.map +1 -0
  69. package/dist/nstbrowser-profile-resolver.d.ts +89 -0
  70. package/dist/nstbrowser-profile-resolver.d.ts.map +1 -0
  71. package/dist/nstbrowser-profile-resolver.js +227 -0
  72. package/dist/nstbrowser-profile-resolver.js.map +1 -0
  73. package/dist/nstbrowser-types.d.ts +151 -0
  74. package/dist/nstbrowser-types.d.ts.map +1 -0
  75. package/dist/nstbrowser-types.js +5 -0
  76. package/dist/nstbrowser-types.js.map +1 -0
  77. package/dist/nstbrowser-utils.d.ts +71 -0
  78. package/dist/nstbrowser-utils.d.ts.map +1 -0
  79. package/dist/nstbrowser-utils.js +174 -0
  80. package/dist/nstbrowser-utils.js.map +1 -0
  81. package/dist/protocol.d.ts +26 -0
  82. package/dist/protocol.d.ts.map +1 -0
  83. package/dist/protocol.js +1245 -0
  84. package/dist/protocol.js.map +1 -0
  85. package/dist/snapshot.d.ts +67 -0
  86. package/dist/snapshot.d.ts.map +1 -0
  87. package/dist/snapshot.js +514 -0
  88. package/dist/snapshot.js.map +1 -0
  89. package/dist/state-utils.d.ts +77 -0
  90. package/dist/state-utils.d.ts.map +1 -0
  91. package/dist/state-utils.js +178 -0
  92. package/dist/state-utils.js.map +1 -0
  93. package/dist/stream-server.d.ts +117 -0
  94. package/dist/stream-server.d.ts.map +1 -0
  95. package/dist/stream-server.js +309 -0
  96. package/dist/stream-server.js.map +1 -0
  97. package/dist/types.d.ts +1121 -0
  98. package/dist/types.d.ts.map +1 -0
  99. package/dist/types.js +2 -0
  100. package/dist/types.js.map +1 -0
  101. package/package.json +83 -0
  102. package/scripts/analyze-api-coverage.js +205 -0
  103. package/scripts/analyze-cli-coverage.js +239 -0
  104. package/scripts/build-all-platforms.sh +68 -0
  105. package/scripts/check-version-sync.js +39 -0
  106. package/scripts/copy-native.js +36 -0
  107. package/scripts/download-nstbrowser-docs.js +152 -0
  108. package/scripts/generate-skills.sh +218 -0
  109. package/scripts/postinstall.js +231 -0
  110. package/scripts/sync-version.js +69 -0
  111. package/skills/nstbrowser-ai-agent/SKILL.md +759 -0
  112. package/skills/nstbrowser-ai-agent/references/batch-operations.md +414 -0
  113. package/skills/nstbrowser-ai-agent/references/nst-api-reference.md +960 -0
  114. package/skills/nstbrowser-ai-agent/references/profile-management.md +672 -0
  115. package/skills/nstbrowser-ai-agent/references/proxy-configuration.md +460 -0
  116. package/skills/nstbrowser-ai-agent/references/troubleshooting.md +773 -0
  117. package/skills/nstbrowser-ai-agent/templates/automated-workflow.sh +248 -0
  118. package/skills/nstbrowser-ai-agent/templates/batch-proxy-update.sh +257 -0
  119. package/skills/nstbrowser-ai-agent/templates/profile-setup.sh +248 -0
@@ -0,0 +1,1245 @@
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
+ // Individual action schemas
8
+ const launchSchema = baseCommandSchema.extend({
9
+ action: z.literal('launch'),
10
+ headless: z.boolean().optional(),
11
+ viewport: z
12
+ .object({
13
+ width: z.number().positive(),
14
+ height: z.number().positive(),
15
+ })
16
+ .nullable()
17
+ .optional(),
18
+ browser: z.enum(['chromium', 'firefox', 'webkit']).optional(),
19
+ cdpPort: z.number().positive().optional(),
20
+ cdpUrl: z
21
+ .string()
22
+ .url()
23
+ .refine((url) => url.startsWith('ws://') ||
24
+ url.startsWith('wss://') ||
25
+ url.startsWith('http://') ||
26
+ url.startsWith('https://'), { message: 'CDP URL must start with ws://, wss://, http://, or https://' })
27
+ .optional(),
28
+ autoConnect: z.boolean().optional(),
29
+ executablePath: z.string().optional(),
30
+ extensions: z.array(z.string()).optional(),
31
+ headers: z.record(z.string()).optional(),
32
+ proxy: z
33
+ .object({
34
+ server: z.string().min(1),
35
+ bypass: z.string().optional(),
36
+ username: z.string().optional(),
37
+ password: z.string().optional(),
38
+ })
39
+ .optional(),
40
+ args: z.array(z.string()).optional(),
41
+ userAgent: z.string().optional(),
42
+ provider: z.string().optional(),
43
+ ignoreHTTPSErrors: z.boolean().optional(),
44
+ allowFileAccess: z.boolean().optional(),
45
+ colorScheme: z.enum(['light', 'dark', 'no-preference']).optional(),
46
+ downloadPath: z.string().optional(),
47
+ profile: z.string().optional(),
48
+ storageState: z.string().optional(),
49
+ allowedDomains: z.array(z.string()).optional(),
50
+ actionPolicy: z.string().optional(),
51
+ confirmActions: z.array(z.string()).optional(),
52
+ nstProfileName: z.string().optional(),
53
+ nstProfileId: z.string().optional(),
54
+ });
55
+ const navigateSchema = baseCommandSchema.extend({
56
+ action: z.literal('navigate'),
57
+ url: z.string().min(1),
58
+ waitUntil: z.enum(['load', 'domcontentloaded', 'networkidle']).optional(),
59
+ headers: z.record(z.string()).optional(),
60
+ });
61
+ const clickSchema = baseCommandSchema.extend({
62
+ action: z.literal('click'),
63
+ selector: z.string().min(1),
64
+ button: z.enum(['left', 'right', 'middle']).optional(),
65
+ clickCount: z.number().positive().optional(),
66
+ delay: z.number().nonnegative().optional(),
67
+ newTab: z.boolean().optional(),
68
+ });
69
+ const typeSchema = baseCommandSchema.extend({
70
+ action: z.literal('type'),
71
+ selector: z.string().min(1),
72
+ text: z.string(),
73
+ delay: z.number().nonnegative().optional(),
74
+ clear: z.boolean().optional(),
75
+ });
76
+ const fillSchema = baseCommandSchema.extend({
77
+ action: z.literal('fill'),
78
+ selector: z.string().min(1),
79
+ value: z.string(),
80
+ });
81
+ const checkSchema = baseCommandSchema.extend({
82
+ action: z.literal('check'),
83
+ selector: z.string().min(1),
84
+ });
85
+ const uncheckSchema = baseCommandSchema.extend({
86
+ action: z.literal('uncheck'),
87
+ selector: z.string().min(1),
88
+ });
89
+ const uploadSchema = baseCommandSchema.extend({
90
+ action: z.literal('upload'),
91
+ selector: z.string().min(1),
92
+ files: z.union([z.string(), z.array(z.string())]),
93
+ });
94
+ const dblclickSchema = baseCommandSchema.extend({
95
+ action: z.literal('dblclick'),
96
+ selector: z.string().min(1),
97
+ });
98
+ const focusSchema = baseCommandSchema.extend({
99
+ action: z.literal('focus'),
100
+ selector: z.string().min(1),
101
+ });
102
+ const dragSchema = baseCommandSchema.extend({
103
+ action: z.literal('drag'),
104
+ source: z.string().min(1),
105
+ target: z.string().min(1),
106
+ });
107
+ const frameSchema = baseCommandSchema.extend({
108
+ action: z.literal('frame'),
109
+ selector: z.string().min(1).optional(),
110
+ name: z.string().optional(),
111
+ url: z.string().optional(),
112
+ });
113
+ const mainframeSchema = baseCommandSchema.extend({
114
+ action: z.literal('mainframe'),
115
+ });
116
+ const getByRoleSchema = baseCommandSchema.extend({
117
+ action: z.literal('getbyrole'),
118
+ role: z.string().min(1),
119
+ name: z.string().optional(),
120
+ exact: z.boolean().optional(),
121
+ subaction: z.enum(['click', 'fill', 'check', 'hover']),
122
+ value: z.string().optional(),
123
+ });
124
+ const getByTextSchema = baseCommandSchema.extend({
125
+ action: z.literal('getbytext'),
126
+ text: z.string().min(1),
127
+ exact: z.boolean().optional(),
128
+ subaction: z.enum(['click', 'hover']),
129
+ });
130
+ const getByLabelSchema = baseCommandSchema.extend({
131
+ action: z.literal('getbylabel'),
132
+ label: z.string().min(1),
133
+ exact: z.boolean().optional(),
134
+ subaction: z.enum(['click', 'fill', 'check']),
135
+ value: z.string().optional(),
136
+ });
137
+ const getByPlaceholderSchema = baseCommandSchema.extend({
138
+ action: z.literal('getbyplaceholder'),
139
+ placeholder: z.string().min(1),
140
+ exact: z.boolean().optional(),
141
+ subaction: z.enum(['click', 'fill']),
142
+ value: z.string().optional(),
143
+ });
144
+ const cookiesGetSchema = baseCommandSchema.extend({
145
+ action: z.literal('cookies_get'),
146
+ urls: z.array(z.string()).optional(),
147
+ });
148
+ const cookiesSetSchema = baseCommandSchema.extend({
149
+ action: z.literal('cookies_set'),
150
+ cookies: z.array(z.object({
151
+ name: z.string(),
152
+ value: z.string(),
153
+ url: z.string().optional(),
154
+ domain: z.string().optional(),
155
+ path: z.string().optional(),
156
+ expires: z.number().optional(),
157
+ httpOnly: z.boolean().optional(),
158
+ secure: z.boolean().optional(),
159
+ sameSite: z.enum(['Strict', 'Lax', 'None']).optional(),
160
+ })),
161
+ });
162
+ const cookiesClearSchema = baseCommandSchema.extend({
163
+ action: z.literal('cookies_clear'),
164
+ });
165
+ const storageGetSchema = baseCommandSchema.extend({
166
+ action: z.literal('storage_get'),
167
+ key: z.string().optional(),
168
+ type: z.enum(['local', 'session']),
169
+ });
170
+ const storageSetSchema = baseCommandSchema.extend({
171
+ action: z.literal('storage_set'),
172
+ key: z.string().min(1),
173
+ value: z.string(),
174
+ type: z.enum(['local', 'session']),
175
+ });
176
+ const storageClearSchema = baseCommandSchema.extend({
177
+ action: z.literal('storage_clear'),
178
+ type: z.enum(['local', 'session']),
179
+ });
180
+ const dialogSchema = baseCommandSchema.extend({
181
+ action: z.literal('dialog'),
182
+ response: z.enum(['accept', 'dismiss']),
183
+ promptText: z.string().optional(),
184
+ });
185
+ const pdfSchema = baseCommandSchema.extend({
186
+ action: z.literal('pdf'),
187
+ path: z.string().min(1),
188
+ format: z
189
+ .enum(['Letter', 'Legal', 'Tabloid', 'Ledger', 'A0', 'A1', 'A2', 'A3', 'A4', 'A5', 'A6'])
190
+ .optional(),
191
+ });
192
+ const routeSchema = baseCommandSchema.extend({
193
+ action: z.literal('route'),
194
+ url: z.string().min(1),
195
+ response: z
196
+ .object({
197
+ status: z.number().optional(),
198
+ body: z.string().optional(),
199
+ contentType: z.string().optional(),
200
+ headers: z.record(z.string()).optional(),
201
+ })
202
+ .optional(),
203
+ abort: z.boolean().optional(),
204
+ });
205
+ const unrouteSchema = baseCommandSchema.extend({
206
+ action: z.literal('unroute'),
207
+ url: z.string().optional(),
208
+ });
209
+ const requestsSchema = baseCommandSchema.extend({
210
+ action: z.literal('requests'),
211
+ filter: z.string().optional(),
212
+ clear: z.boolean().optional(),
213
+ });
214
+ const downloadSchema = baseCommandSchema.extend({
215
+ action: z.literal('download'),
216
+ selector: z.string().min(1),
217
+ path: z.string().min(1),
218
+ });
219
+ const geolocationSchema = baseCommandSchema.extend({
220
+ action: z.literal('geolocation'),
221
+ latitude: z.number(),
222
+ longitude: z.number(),
223
+ accuracy: z.number().optional(),
224
+ });
225
+ const permissionsSchema = baseCommandSchema.extend({
226
+ action: z.literal('permissions'),
227
+ permissions: z.array(z.string()),
228
+ grant: z.boolean(),
229
+ });
230
+ const viewportSchema = baseCommandSchema.extend({
231
+ action: z.literal('viewport'),
232
+ width: z.number().positive(),
233
+ height: z.number().positive(),
234
+ });
235
+ const userAgentSchema = baseCommandSchema.extend({
236
+ action: z.literal('useragent'),
237
+ userAgent: z.string().min(1),
238
+ });
239
+ const deviceSchema = baseCommandSchema.extend({
240
+ action: z.literal('device'),
241
+ device: z.string().min(1),
242
+ });
243
+ const backSchema = baseCommandSchema.extend({
244
+ action: z.literal('back'),
245
+ });
246
+ const forwardSchema = baseCommandSchema.extend({
247
+ action: z.literal('forward'),
248
+ });
249
+ const reloadSchema = baseCommandSchema.extend({
250
+ action: z.literal('reload'),
251
+ });
252
+ const urlSchema = baseCommandSchema.extend({
253
+ action: z.literal('url'),
254
+ });
255
+ const titleSchema = baseCommandSchema.extend({
256
+ action: z.literal('title'),
257
+ });
258
+ const getAttributeSchema = baseCommandSchema.extend({
259
+ action: z.literal('getattribute'),
260
+ selector: z.string().min(1),
261
+ attribute: z.string().min(1),
262
+ });
263
+ const getTextSchema = baseCommandSchema.extend({
264
+ action: z.literal('gettext'),
265
+ selector: z.string().min(1),
266
+ });
267
+ const isVisibleSchema = baseCommandSchema.extend({
268
+ action: z.literal('isvisible'),
269
+ selector: z.string().min(1),
270
+ });
271
+ const isEnabledSchema = baseCommandSchema.extend({
272
+ action: z.literal('isenabled'),
273
+ selector: z.string().min(1),
274
+ });
275
+ const isCheckedSchema = baseCommandSchema.extend({
276
+ action: z.literal('ischecked'),
277
+ selector: z.string().min(1),
278
+ });
279
+ const countSchema = baseCommandSchema.extend({
280
+ action: z.literal('count'),
281
+ selector: z.string().min(1),
282
+ });
283
+ const boundingBoxSchema = baseCommandSchema.extend({
284
+ action: z.literal('boundingbox'),
285
+ selector: z.string().min(1),
286
+ });
287
+ const stylesSchema = baseCommandSchema.extend({
288
+ action: z.literal('styles'),
289
+ selector: z.string().min(1),
290
+ });
291
+ const videoStartSchema = baseCommandSchema.extend({
292
+ action: z.literal('video_start'),
293
+ path: z.string().min(1),
294
+ });
295
+ const videoStopSchema = baseCommandSchema.extend({
296
+ action: z.literal('video_stop'),
297
+ });
298
+ // Recording schemas (Playwright native video recording)
299
+ const recordingStartSchema = baseCommandSchema.extend({
300
+ action: z.literal('recording_start'),
301
+ path: z.string().min(1),
302
+ url: z.string().min(1).optional(),
303
+ });
304
+ const recordingStopSchema = baseCommandSchema.extend({
305
+ action: z.literal('recording_stop'),
306
+ });
307
+ const recordingRestartSchema = baseCommandSchema.extend({
308
+ action: z.literal('recording_restart'),
309
+ path: z.string().min(1),
310
+ url: z.string().min(1).optional(),
311
+ });
312
+ const traceStartSchema = baseCommandSchema.extend({
313
+ action: z.literal('trace_start'),
314
+ screenshots: z.boolean().optional(),
315
+ snapshots: z.boolean().optional(),
316
+ });
317
+ const traceStopSchema = baseCommandSchema.extend({
318
+ action: z.literal('trace_stop'),
319
+ path: z.string().min(1).optional(),
320
+ });
321
+ const profilerStartSchema = baseCommandSchema.extend({
322
+ action: z.literal('profiler_start'),
323
+ categories: z.array(z.string()).optional(),
324
+ });
325
+ const profilerStopSchema = baseCommandSchema.extend({
326
+ action: z.literal('profiler_stop'),
327
+ path: z.string().min(1).optional(),
328
+ });
329
+ const harStartSchema = baseCommandSchema.extend({
330
+ action: z.literal('har_start'),
331
+ });
332
+ const harStopSchema = baseCommandSchema.extend({
333
+ action: z.literal('har_stop'),
334
+ path: z.string().min(1),
335
+ });
336
+ const stateSaveSchema = baseCommandSchema.extend({
337
+ action: z.literal('state_save'),
338
+ path: z.string().min(1),
339
+ });
340
+ const stateLoadSchema = baseCommandSchema.extend({
341
+ action: z.literal('state_load'),
342
+ path: z.string().min(1),
343
+ });
344
+ const stateListSchema = baseCommandSchema.extend({
345
+ action: z.literal('state_list'),
346
+ });
347
+ const stateClearSchema = baseCommandSchema.extend({
348
+ action: z.literal('state_clear'),
349
+ sessionName: z.string().optional(),
350
+ all: z.boolean().optional(),
351
+ });
352
+ const stateShowSchema = baseCommandSchema.extend({
353
+ action: z.literal('state_show'),
354
+ filename: z.string().min(1),
355
+ });
356
+ const stateCleanSchema = baseCommandSchema.extend({
357
+ action: z.literal('state_clean'),
358
+ days: z.number().int().positive(),
359
+ });
360
+ const stateRenameSchema = baseCommandSchema.extend({
361
+ action: z.literal('state_rename'),
362
+ oldName: z.string().min(1),
363
+ newName: z.string().min(1),
364
+ });
365
+ const consoleSchema = baseCommandSchema.extend({
366
+ action: z.literal('console'),
367
+ clear: z.boolean().optional(),
368
+ });
369
+ const errorsSchema = baseCommandSchema.extend({
370
+ action: z.literal('errors'),
371
+ clear: z.boolean().optional(),
372
+ });
373
+ const keyboardSchema = baseCommandSchema.extend({
374
+ action: z.literal('keyboard'),
375
+ subaction: z.enum(['type', 'press', 'insertText']).optional(),
376
+ keys: z.string().min(1).optional(),
377
+ text: z.string().min(1).optional(),
378
+ delay: z.number().optional(),
379
+ });
380
+ const wheelSchema = baseCommandSchema.extend({
381
+ action: z.literal('wheel'),
382
+ deltaX: z.number().optional(),
383
+ deltaY: z.number().optional(),
384
+ selector: z.string().optional(),
385
+ });
386
+ const tapSchema = baseCommandSchema.extend({
387
+ action: z.literal('tap'),
388
+ selector: z.string().min(1),
389
+ });
390
+ const clipboardSchema = baseCommandSchema.extend({
391
+ action: z.literal('clipboard'),
392
+ operation: z.enum(['copy', 'paste', 'read']),
393
+ text: z.string().optional(),
394
+ });
395
+ const highlightSchema = baseCommandSchema.extend({
396
+ action: z.literal('highlight'),
397
+ selector: z.string().min(1),
398
+ });
399
+ const clearSchema = baseCommandSchema.extend({
400
+ action: z.literal('clear'),
401
+ selector: z.string().min(1),
402
+ });
403
+ const selectAllSchema = baseCommandSchema.extend({
404
+ action: z.literal('selectall'),
405
+ selector: z.string().min(1),
406
+ });
407
+ const innerTextSchema = baseCommandSchema.extend({
408
+ action: z.literal('innertext'),
409
+ selector: z.string().min(1),
410
+ });
411
+ const innerHtmlSchema = baseCommandSchema.extend({
412
+ action: z.literal('innerhtml'),
413
+ selector: z.string().min(1),
414
+ });
415
+ const inputValueSchema = baseCommandSchema.extend({
416
+ action: z.literal('inputvalue'),
417
+ selector: z.string().min(1),
418
+ });
419
+ const setValueSchema = baseCommandSchema.extend({
420
+ action: z.literal('setvalue'),
421
+ selector: z.string().min(1),
422
+ value: z.string(),
423
+ });
424
+ const dispatchSchema = baseCommandSchema.extend({
425
+ action: z.literal('dispatch'),
426
+ selector: z.string().min(1),
427
+ event: z.string().min(1),
428
+ eventInit: z.record(z.unknown()).optional(),
429
+ });
430
+ const evalHandleSchema = baseCommandSchema.extend({
431
+ action: z.literal('evalhandle'),
432
+ script: z.string().min(1),
433
+ });
434
+ const exposeSchema = baseCommandSchema.extend({
435
+ action: z.literal('expose'),
436
+ name: z.string().min(1),
437
+ });
438
+ const addScriptSchema = baseCommandSchema.extend({
439
+ action: z.literal('addscript'),
440
+ content: z.string().optional(),
441
+ url: z.string().optional(),
442
+ });
443
+ const addStyleSchema = baseCommandSchema.extend({
444
+ action: z.literal('addstyle'),
445
+ content: z.string().optional(),
446
+ url: z.string().optional(),
447
+ });
448
+ const emulateMediaSchema = baseCommandSchema.extend({
449
+ action: z.literal('emulatemedia'),
450
+ media: z.enum(['screen', 'print']).nullable().optional(),
451
+ colorScheme: z.enum(['light', 'dark', 'no-preference']).nullable().optional(),
452
+ reducedMotion: z.enum(['reduce', 'no-preference']).nullable().optional(),
453
+ forcedColors: z.enum(['active', 'none']).nullable().optional(),
454
+ });
455
+ const offlineSchema = baseCommandSchema.extend({
456
+ action: z.literal('offline'),
457
+ offline: z.boolean(),
458
+ });
459
+ const headersSchema = baseCommandSchema.extend({
460
+ action: z.literal('headers'),
461
+ headers: z.record(z.string()),
462
+ });
463
+ const pauseSchema = baseCommandSchema.extend({
464
+ action: z.literal('pause'),
465
+ });
466
+ const getByAltTextSchema = baseCommandSchema.extend({
467
+ action: z.literal('getbyalttext'),
468
+ text: z.string().min(1),
469
+ exact: z.boolean().optional(),
470
+ subaction: z.enum(['click', 'hover']),
471
+ });
472
+ const getByTitleSchema = baseCommandSchema.extend({
473
+ action: z.literal('getbytitle'),
474
+ text: z.string().min(1),
475
+ exact: z.boolean().optional(),
476
+ subaction: z.enum(['click', 'hover']),
477
+ });
478
+ const getByTestIdSchema = baseCommandSchema.extend({
479
+ action: z.literal('getbytestid'),
480
+ testId: z.string().min(1),
481
+ subaction: z.enum(['click', 'fill', 'check', 'hover']),
482
+ value: z.string().optional(),
483
+ });
484
+ const nthSchema = baseCommandSchema.extend({
485
+ action: z.literal('nth'),
486
+ selector: z.string().min(1),
487
+ index: z.number(),
488
+ subaction: z.enum(['click', 'fill', 'check', 'hover', 'text']),
489
+ value: z.string().optional(),
490
+ });
491
+ const waitForUrlSchema = baseCommandSchema.extend({
492
+ action: z.literal('waitforurl'),
493
+ url: z.string().min(1),
494
+ timeout: z.number().positive().optional(),
495
+ });
496
+ const waitForLoadStateSchema = baseCommandSchema.extend({
497
+ action: z.literal('waitforloadstate'),
498
+ state: z.enum(['load', 'domcontentloaded', 'networkidle']),
499
+ timeout: z.number().positive().optional(),
500
+ });
501
+ const setContentSchema = baseCommandSchema.extend({
502
+ action: z.literal('setcontent'),
503
+ html: z.string(),
504
+ });
505
+ const timezoneSchema = baseCommandSchema.extend({
506
+ action: z.literal('timezone'),
507
+ timezone: z.string().min(1),
508
+ });
509
+ const localeSchema = baseCommandSchema.extend({
510
+ action: z.literal('locale'),
511
+ locale: z.string().min(1),
512
+ });
513
+ const credentialsSchema = baseCommandSchema.extend({
514
+ action: z.literal('credentials'),
515
+ username: z.string(),
516
+ password: z.string(),
517
+ });
518
+ const mouseMoveSchema = baseCommandSchema.extend({
519
+ action: z.literal('mousemove'),
520
+ x: z.number(),
521
+ y: z.number(),
522
+ });
523
+ const mouseDownSchema = baseCommandSchema.extend({
524
+ action: z.literal('mousedown'),
525
+ button: z.enum(['left', 'right', 'middle']).optional(),
526
+ });
527
+ const mouseUpSchema = baseCommandSchema.extend({
528
+ action: z.literal('mouseup'),
529
+ button: z.enum(['left', 'right', 'middle']).optional(),
530
+ });
531
+ const bringToFrontSchema = baseCommandSchema.extend({
532
+ action: z.literal('bringtofront'),
533
+ });
534
+ const waitForFunctionSchema = baseCommandSchema.extend({
535
+ action: z.literal('waitforfunction'),
536
+ expression: z.string().min(1),
537
+ timeout: z.number().positive().optional(),
538
+ });
539
+ const scrollIntoViewSchema = baseCommandSchema.extend({
540
+ action: z.literal('scrollintoview'),
541
+ selector: z.string().min(1),
542
+ });
543
+ const addInitScriptSchema = baseCommandSchema.extend({
544
+ action: z.literal('addinitscript'),
545
+ script: z.string().min(1),
546
+ });
547
+ const keyDownSchema = baseCommandSchema.extend({
548
+ action: z.literal('keydown'),
549
+ key: z.string().min(1),
550
+ });
551
+ const keyUpSchema = baseCommandSchema.extend({
552
+ action: z.literal('keyup'),
553
+ key: z.string().min(1),
554
+ });
555
+ const insertTextSchema = baseCommandSchema.extend({
556
+ action: z.literal('inserttext'),
557
+ text: z.string(),
558
+ });
559
+ const multiSelectSchema = baseCommandSchema.extend({
560
+ action: z.literal('multiselect'),
561
+ selector: z.string().min(1),
562
+ values: z.array(z.string()),
563
+ });
564
+ const waitForDownloadSchema = baseCommandSchema.extend({
565
+ action: z.literal('waitfordownload'),
566
+ path: z.string().optional(),
567
+ timeout: z.number().positive().optional(),
568
+ });
569
+ const responseBodySchema = baseCommandSchema.extend({
570
+ action: z.literal('responsebody'),
571
+ url: z.string().min(1),
572
+ timeout: z.number().positive().optional(),
573
+ });
574
+ // Screencast schemas for streaming browser viewport
575
+ const screencastStartSchema = baseCommandSchema.extend({
576
+ action: z.literal('screencast_start'),
577
+ format: z.enum(['jpeg', 'png']).optional(),
578
+ quality: z.number().min(0).max(100).optional(),
579
+ maxWidth: z.number().positive().optional(),
580
+ maxHeight: z.number().positive().optional(),
581
+ everyNthFrame: z.number().positive().optional(),
582
+ });
583
+ const screencastStopSchema = baseCommandSchema.extend({
584
+ action: z.literal('screencast_stop'),
585
+ });
586
+ // Input injection schemas for pair browsing
587
+ const inputMouseSchema = baseCommandSchema.extend({
588
+ action: z.literal('input_mouse'),
589
+ type: z.enum(['mousePressed', 'mouseReleased', 'mouseMoved', 'mouseWheel']),
590
+ x: z.number(),
591
+ y: z.number(),
592
+ button: z.enum(['left', 'right', 'middle', 'none']).optional(),
593
+ clickCount: z.number().positive().optional(),
594
+ deltaX: z.number().optional(),
595
+ deltaY: z.number().optional(),
596
+ modifiers: z.number().optional(),
597
+ });
598
+ const inputKeyboardSchema = baseCommandSchema.extend({
599
+ action: z.literal('input_keyboard'),
600
+ type: z.enum(['keyDown', 'keyUp', 'char']),
601
+ key: z.string().optional(),
602
+ code: z.string().optional(),
603
+ text: z.string().optional(),
604
+ modifiers: z.number().optional(),
605
+ });
606
+ const inputTouchSchema = baseCommandSchema.extend({
607
+ action: z.literal('input_touch'),
608
+ type: z.enum(['touchStart', 'touchEnd', 'touchMove', 'touchCancel']),
609
+ touchPoints: z.array(z.object({
610
+ x: z.number(),
611
+ y: z.number(),
612
+ id: z.number().optional(),
613
+ })),
614
+ modifiers: z.number().optional(),
615
+ });
616
+ // iOS-specific schemas
617
+ const swipeSchema = baseCommandSchema.extend({
618
+ action: z.literal('swipe'),
619
+ direction: z.enum(['up', 'down', 'left', 'right']),
620
+ distance: z.number().positive().optional(),
621
+ });
622
+ const deviceListSchema = baseCommandSchema.extend({
623
+ action: z.literal('device_list'),
624
+ });
625
+ // Diff schemas
626
+ const diffSnapshotSchema = baseCommandSchema.extend({
627
+ action: z.literal('diff_snapshot'),
628
+ baseline: z.string().optional(),
629
+ selector: z.string().optional(),
630
+ compact: z.boolean().optional(),
631
+ maxDepth: z.number().nonnegative().optional(),
632
+ });
633
+ const diffScreenshotSchema = baseCommandSchema.extend({
634
+ action: z.literal('diff_screenshot'),
635
+ baseline: z.string().min(1),
636
+ output: z.string().optional(),
637
+ threshold: z.number().min(0).max(1).optional(),
638
+ selector: z.string().min(1).optional(),
639
+ fullPage: z.boolean().optional(),
640
+ });
641
+ const diffUrlSchema = baseCommandSchema.extend({
642
+ action: z.literal('diff_url'),
643
+ url1: z.string().min(1),
644
+ url2: z.string().min(1),
645
+ screenshot: z.boolean().optional(),
646
+ fullPage: z.boolean().optional(),
647
+ waitUntil: z.enum(['load', 'domcontentloaded', 'networkidle']).optional(),
648
+ selector: z.string().optional(),
649
+ compact: z.boolean().optional(),
650
+ maxDepth: z.number().nonnegative().optional(),
651
+ });
652
+ const pressSchema = baseCommandSchema.extend({
653
+ action: z.literal('press'),
654
+ key: z.string().min(1),
655
+ selector: z.string().min(1).optional(),
656
+ });
657
+ const screenshotSchema = baseCommandSchema.extend({
658
+ action: z.literal('screenshot'),
659
+ path: z.string().nullable().optional(),
660
+ fullPage: z.boolean().optional(),
661
+ selector: z.string().min(1).nullish(),
662
+ format: z.enum(['png', 'jpeg']).optional(),
663
+ quality: z.number().min(0).max(100).optional(),
664
+ annotate: z.boolean().optional(),
665
+ });
666
+ const snapshotSchema = baseCommandSchema.extend({
667
+ action: z.literal('snapshot'),
668
+ interactive: z.boolean().optional(),
669
+ cursor: z.boolean().optional(),
670
+ maxDepth: z.number().nonnegative().optional(),
671
+ compact: z.boolean().optional(),
672
+ selector: z.string().optional(),
673
+ });
674
+ const evaluateSchema = baseCommandSchema.extend({
675
+ action: z.literal('evaluate'),
676
+ script: z.string().min(1),
677
+ args: z.array(z.unknown()).optional(),
678
+ });
679
+ const waitSchema = baseCommandSchema.extend({
680
+ action: z.literal('wait'),
681
+ selector: z.string().min(1).optional(),
682
+ timeout: z.number().positive().optional(),
683
+ state: z.enum(['attached', 'detached', 'visible', 'hidden']).optional(),
684
+ });
685
+ const scrollSchema = baseCommandSchema.extend({
686
+ action: z.literal('scroll'),
687
+ selector: z.string().min(1).optional(),
688
+ x: z.number().optional(),
689
+ y: z.number().optional(),
690
+ direction: z.enum(['up', 'down', 'left', 'right']).optional(),
691
+ amount: z.number().positive().optional(),
692
+ });
693
+ const selectSchema = baseCommandSchema.extend({
694
+ action: z.literal('select'),
695
+ selector: z.string().min(1),
696
+ values: z.union([z.string(), z.array(z.string())]),
697
+ });
698
+ const hoverSchema = baseCommandSchema.extend({
699
+ action: z.literal('hover'),
700
+ selector: z.string().min(1),
701
+ });
702
+ const contentSchema = baseCommandSchema.extend({
703
+ action: z.literal('content'),
704
+ selector: z.string().min(1).optional(),
705
+ });
706
+ const closeSchema = baseCommandSchema.extend({
707
+ action: z.literal('close'),
708
+ });
709
+ // Tab/Window schemas
710
+ const tabNewSchema = baseCommandSchema.extend({
711
+ action: z.literal('tab_new'),
712
+ url: z.string().min(1).optional(),
713
+ });
714
+ const tabListSchema = baseCommandSchema.extend({
715
+ action: z.literal('tab_list'),
716
+ });
717
+ const tabSwitchSchema = baseCommandSchema.extend({
718
+ action: z.literal('tab_switch'),
719
+ index: z.number().nonnegative(),
720
+ });
721
+ const tabCloseSchema = baseCommandSchema.extend({
722
+ action: z.literal('tab_close'),
723
+ index: z.number().nonnegative().optional(),
724
+ });
725
+ const windowNewSchema = baseCommandSchema.extend({
726
+ action: z.literal('window_new'),
727
+ viewport: z
728
+ .object({
729
+ width: z.number().positive(),
730
+ height: z.number().positive(),
731
+ })
732
+ .nullable()
733
+ .optional(),
734
+ });
735
+ const authProfileName = z
736
+ .string()
737
+ .min(1)
738
+ .regex(/^[a-zA-Z0-9_-]+$/, {
739
+ message: 'Profile name must contain only alphanumeric characters, hyphens, and underscores',
740
+ });
741
+ const authSaveSchema = baseCommandSchema.extend({
742
+ action: z.literal('auth_save'),
743
+ name: authProfileName,
744
+ url: z.string().min(1),
745
+ username: z.string().min(1),
746
+ password: z.string().min(1),
747
+ usernameSelector: z.string().optional(),
748
+ passwordSelector: z.string().optional(),
749
+ submitSelector: z.string().optional(),
750
+ });
751
+ const authLoginSchema = baseCommandSchema.extend({
752
+ action: z.literal('auth_login'),
753
+ name: authProfileName,
754
+ });
755
+ const authListSchema = baseCommandSchema.extend({
756
+ action: z.literal('auth_list'),
757
+ });
758
+ const authDeleteSchema = baseCommandSchema.extend({
759
+ action: z.literal('auth_delete'),
760
+ name: authProfileName,
761
+ });
762
+ const authShowSchema = baseCommandSchema.extend({
763
+ action: z.literal('auth_show'),
764
+ name: authProfileName,
765
+ });
766
+ const confirmSchema = baseCommandSchema.extend({
767
+ action: z.literal('confirm'),
768
+ confirmationId: z.string().min(1),
769
+ });
770
+ const denySchema = baseCommandSchema.extend({
771
+ action: z.literal('deny'),
772
+ confirmationId: z.string().min(1),
773
+ });
774
+ // ==================== Nstbrowser Commands ====================
775
+ const nstBrowserListSchema = baseCommandSchema.extend({
776
+ action: z.literal('nst_browser_list'),
777
+ });
778
+ const nstBrowserStartSchema = baseCommandSchema.extend({
779
+ action: z.literal('nst_browser_start'),
780
+ profileId: z.string().min(1),
781
+ options: z
782
+ .object({
783
+ headless: z.boolean().optional(),
784
+ autoClose: z.boolean().optional(),
785
+ timedCloseSec: z.number().optional(),
786
+ clearCacheOnClose: z.boolean().optional(),
787
+ incognito: z.boolean().optional(),
788
+ restoreLastSession: z.boolean().optional(),
789
+ disableImageLoading: z.boolean().optional(),
790
+ doNotTrack: z.boolean().optional(),
791
+ args: z.array(z.string()).optional(),
792
+ skipProxyChecking: z.boolean().optional(),
793
+ })
794
+ .optional(),
795
+ });
796
+ const nstBrowserStopSchema = baseCommandSchema.extend({
797
+ action: z.literal('nst_browser_stop'),
798
+ profileId: z.string().min(1),
799
+ });
800
+ const nstBrowserStopAllSchema = baseCommandSchema.extend({
801
+ action: z.literal('nst_browser_stop_all'),
802
+ });
803
+ const nstProfileListSchema = baseCommandSchema.extend({
804
+ action: z.literal('nst_profile_list'),
805
+ query: z
806
+ .object({
807
+ name: z.string().optional(),
808
+ groupId: z.string().optional(),
809
+ platform: z.enum(['Windows', 'macOS', 'Linux']).optional(),
810
+ })
811
+ .optional(),
812
+ });
813
+ const nstProfileCreateSchema = baseCommandSchema.extend({
814
+ action: z.literal('nst_profile_create'),
815
+ name: z.string().min(1),
816
+ proxyConfig: z
817
+ .object({
818
+ type: z.enum(['http', 'https', 'socks5']),
819
+ host: z.string(),
820
+ port: z.number(),
821
+ username: z.string().optional(),
822
+ password: z.string().optional(),
823
+ enabled: z.boolean().optional(),
824
+ })
825
+ .optional(),
826
+ platform: z.enum(['Windows', 'macOS', 'Linux']).optional(),
827
+ kernel: z.string().optional(),
828
+ fingerprint: z.record(z.unknown()).optional(),
829
+ groupId: z.string().optional(),
830
+ });
831
+ const nstProfileDeleteSchema = baseCommandSchema.extend({
832
+ action: z.literal('nst_profile_delete'),
833
+ profileIds: z.array(z.string().min(1)).min(1),
834
+ });
835
+ const nstProfileProxyUpdateSchema = baseCommandSchema.extend({
836
+ action: z.literal('nst_profile_proxy_update'),
837
+ profileId: z.string().min(1),
838
+ proxyConfig: z.object({
839
+ type: z.enum(['http', 'https', 'socks5']),
840
+ host: z.string(),
841
+ port: z.number(),
842
+ username: z.string().optional(),
843
+ password: z.string().optional(),
844
+ }),
845
+ });
846
+ const nstProfileProxyResetSchema = baseCommandSchema.extend({
847
+ action: z.literal('nst_profile_proxy_reset'),
848
+ profileIds: z.array(z.string().min(1)).min(1),
849
+ });
850
+ const nstProfileTagsListSchema = baseCommandSchema.extend({
851
+ action: z.literal('nst_profile_tags_list'),
852
+ });
853
+ const nstProfileTagsCreateSchema = baseCommandSchema.extend({
854
+ action: z.literal('nst_profile_tags_create'),
855
+ profileId: z.string().min(1),
856
+ tag: z.string().min(1),
857
+ });
858
+ const nstProfileTagsClearSchema = baseCommandSchema.extend({
859
+ action: z.literal('nst_profile_tags_clear'),
860
+ profileIds: z.array(z.string().min(1)).min(1),
861
+ });
862
+ const nstProfileGroupsListSchema = baseCommandSchema.extend({
863
+ action: z.literal('nst_profile_groups_list'),
864
+ });
865
+ const nstProfileGroupChangeSchema = baseCommandSchema.extend({
866
+ action: z.literal('nst_profile_group_change'),
867
+ groupId: z.string().min(1),
868
+ profileIds: z.array(z.string().min(1)).min(1),
869
+ });
870
+ const nstProfileCacheClearSchema = baseCommandSchema.extend({
871
+ action: z.literal('nst_profile_cache_clear'),
872
+ profileIds: z.array(z.string().min(1)).min(1),
873
+ });
874
+ const nstProfileCookiesClearSchema = baseCommandSchema.extend({
875
+ action: z.literal('nst_profile_cookies_clear'),
876
+ profileIds: z.array(z.string().min(1)).min(1),
877
+ });
878
+ // New Nstbrowser commands
879
+ const nstProfileShowSchema = baseCommandSchema.extend({
880
+ action: z.literal('nst_profile_show'),
881
+ profileId: z.string().min(1),
882
+ });
883
+ const nstProfileProxyShowSchema = baseCommandSchema.extend({
884
+ action: z.literal('nst_profile_proxy_show'),
885
+ profileId: z.string().min(1),
886
+ });
887
+ const nstBrowserPagesSchema = baseCommandSchema.extend({
888
+ action: z.literal('nst_browser_pages'),
889
+ profileId: z.string().min(1),
890
+ });
891
+ const nstBrowserDebuggerSchema = baseCommandSchema.extend({
892
+ action: z.literal('nst_browser_debugger'),
893
+ profileId: z.string().min(1),
894
+ });
895
+ const nstProfileTagsUpdateSchema = baseCommandSchema.extend({
896
+ action: z.literal('nst_profile_tags_update'),
897
+ profileId: z.string().min(1),
898
+ tags: z.array(z.object({
899
+ name: z.string().min(1),
900
+ color: z.string().optional(),
901
+ })),
902
+ });
903
+ const nstProfileProxyBatchUpdateSchema = baseCommandSchema.extend({
904
+ action: z.literal('nst_profile_proxy_batch_update'),
905
+ profileIds: z.array(z.string().min(1)).min(1),
906
+ proxyConfig: z.object({
907
+ type: z.enum(['http', 'https', 'socks5']),
908
+ host: z.string(),
909
+ port: z.number(),
910
+ username: z.string().optional(),
911
+ password: z.string().optional(),
912
+ }),
913
+ });
914
+ const nstProfileProxyBatchResetSchema = baseCommandSchema.extend({
915
+ action: z.literal('nst_profile_proxy_batch_reset'),
916
+ profileIds: z.array(z.string().min(1)).min(1),
917
+ });
918
+ const nstProfileTagsBatchCreateSchema = baseCommandSchema.extend({
919
+ action: z.literal('nst_profile_tags_batch_create'),
920
+ profileIds: z.array(z.string().min(1)).min(1),
921
+ tags: z.array(z.object({
922
+ name: z.string().min(1),
923
+ color: z.string().optional(),
924
+ })),
925
+ });
926
+ const nstProfileTagsBatchUpdateSchema = baseCommandSchema.extend({
927
+ action: z.literal('nst_profile_tags_batch_update'),
928
+ profileIds: z.array(z.string().min(1)).min(1),
929
+ tags: z.array(z.object({
930
+ name: z.string().min(1),
931
+ color: z.string().optional(),
932
+ })),
933
+ });
934
+ const nstProfileTagsBatchClearSchema = baseCommandSchema.extend({
935
+ action: z.literal('nst_profile_tags_batch_clear'),
936
+ profileIds: z.array(z.string().min(1)).min(1),
937
+ });
938
+ const nstProfileGroupBatchChangeSchema = baseCommandSchema.extend({
939
+ action: z.literal('nst_profile_group_batch_change'),
940
+ profileIds: z.array(z.string().min(1)).min(1),
941
+ groupId: z.string().min(1),
942
+ });
943
+ // New commands - Batch operations and CDP endpoints
944
+ const nstBrowserStartBatchSchema = baseCommandSchema.extend({
945
+ action: z.literal('nst_browser_start_batch'),
946
+ profileIds: z.array(z.string().min(1)).min(1),
947
+ config: z
948
+ .object({
949
+ remoteDebuggingPort: z.number().optional(),
950
+ headless: z.boolean().optional(),
951
+ disableGpu: z.boolean().optional(),
952
+ proxyEnabled: z.boolean().optional(),
953
+ autoClose: z.boolean().optional(),
954
+ })
955
+ .optional(),
956
+ });
957
+ const nstBrowserStartOnceSchema = baseCommandSchema.extend({
958
+ action: z.literal('nst_browser_start_once'),
959
+ config: z
960
+ .object({
961
+ platform: z.enum(['Windows', 'macOS', 'Linux']).optional(),
962
+ kernel: z.string().optional(),
963
+ fingerprint: z.record(z.unknown()).optional(),
964
+ remoteDebuggingPort: z.number().optional(),
965
+ headless: z.boolean().optional(),
966
+ disableGpu: z.boolean().optional(),
967
+ proxyEnabled: z.boolean().optional(),
968
+ autoClose: z.boolean().optional(),
969
+ })
970
+ .optional(),
971
+ });
972
+ const nstProfileListCursorSchema = baseCommandSchema.extend({
973
+ action: z.literal('nst_profile_list_cursor'),
974
+ cursor: z.string().optional(),
975
+ pageSize: z.number().optional(),
976
+ direction: z.enum(['next', 'prev']).optional(),
977
+ });
978
+ const nstBrowserConnectSchema = baseCommandSchema.extend({
979
+ action: z.literal('nst_browser_connect'),
980
+ profileId: z.string().min(1),
981
+ });
982
+ const nstBrowserConnectOnceSchema = baseCommandSchema.extend({
983
+ action: z.literal('nst_browser_connect_once'),
984
+ config: z
985
+ .object({
986
+ platform: z.enum(['Windows', 'macOS', 'Linux']).optional(),
987
+ kernel: z.string().optional(),
988
+ fingerprint: z.record(z.unknown()).optional(),
989
+ })
990
+ .optional(),
991
+ });
992
+ const nstBrowserCdpUrlSchema = baseCommandSchema.extend({
993
+ action: z.literal('nst_browser_cdp_url'),
994
+ profileId: z.string().min(1),
995
+ });
996
+ const nstBrowserCdpUrlOnceSchema = baseCommandSchema.extend({
997
+ action: z.literal('nst_browser_cdp_url_once'),
998
+ });
999
+ // Union schema for all commands
1000
+ const commandSchema = z.discriminatedUnion('action', [
1001
+ launchSchema,
1002
+ navigateSchema,
1003
+ clickSchema,
1004
+ typeSchema,
1005
+ fillSchema,
1006
+ checkSchema,
1007
+ uncheckSchema,
1008
+ uploadSchema,
1009
+ dblclickSchema,
1010
+ focusSchema,
1011
+ dragSchema,
1012
+ frameSchema,
1013
+ mainframeSchema,
1014
+ getByRoleSchema,
1015
+ getByTextSchema,
1016
+ getByLabelSchema,
1017
+ getByPlaceholderSchema,
1018
+ pressSchema,
1019
+ screenshotSchema,
1020
+ snapshotSchema,
1021
+ evaluateSchema,
1022
+ waitSchema,
1023
+ scrollSchema,
1024
+ selectSchema,
1025
+ hoverSchema,
1026
+ contentSchema,
1027
+ closeSchema,
1028
+ tabNewSchema,
1029
+ tabListSchema,
1030
+ tabSwitchSchema,
1031
+ tabCloseSchema,
1032
+ windowNewSchema,
1033
+ cookiesGetSchema,
1034
+ cookiesSetSchema,
1035
+ cookiesClearSchema,
1036
+ storageGetSchema,
1037
+ storageSetSchema,
1038
+ storageClearSchema,
1039
+ dialogSchema,
1040
+ pdfSchema,
1041
+ routeSchema,
1042
+ unrouteSchema,
1043
+ requestsSchema,
1044
+ downloadSchema,
1045
+ geolocationSchema,
1046
+ permissionsSchema,
1047
+ viewportSchema,
1048
+ userAgentSchema,
1049
+ deviceSchema,
1050
+ backSchema,
1051
+ forwardSchema,
1052
+ reloadSchema,
1053
+ urlSchema,
1054
+ titleSchema,
1055
+ getAttributeSchema,
1056
+ getTextSchema,
1057
+ isVisibleSchema,
1058
+ isEnabledSchema,
1059
+ isCheckedSchema,
1060
+ countSchema,
1061
+ boundingBoxSchema,
1062
+ stylesSchema,
1063
+ videoStartSchema,
1064
+ videoStopSchema,
1065
+ recordingStartSchema,
1066
+ recordingStopSchema,
1067
+ recordingRestartSchema,
1068
+ traceStartSchema,
1069
+ traceStopSchema,
1070
+ profilerStartSchema,
1071
+ profilerStopSchema,
1072
+ harStartSchema,
1073
+ harStopSchema,
1074
+ stateSaveSchema,
1075
+ stateLoadSchema,
1076
+ stateListSchema,
1077
+ stateClearSchema,
1078
+ stateShowSchema,
1079
+ stateCleanSchema,
1080
+ stateRenameSchema,
1081
+ consoleSchema,
1082
+ errorsSchema,
1083
+ keyboardSchema,
1084
+ wheelSchema,
1085
+ tapSchema,
1086
+ clipboardSchema,
1087
+ highlightSchema,
1088
+ clearSchema,
1089
+ selectAllSchema,
1090
+ innerTextSchema,
1091
+ innerHtmlSchema,
1092
+ inputValueSchema,
1093
+ setValueSchema,
1094
+ dispatchSchema,
1095
+ evalHandleSchema,
1096
+ exposeSchema,
1097
+ addScriptSchema,
1098
+ addStyleSchema,
1099
+ emulateMediaSchema,
1100
+ offlineSchema,
1101
+ headersSchema,
1102
+ pauseSchema,
1103
+ getByAltTextSchema,
1104
+ getByTitleSchema,
1105
+ getByTestIdSchema,
1106
+ nthSchema,
1107
+ waitForUrlSchema,
1108
+ waitForLoadStateSchema,
1109
+ setContentSchema,
1110
+ timezoneSchema,
1111
+ localeSchema,
1112
+ credentialsSchema,
1113
+ mouseMoveSchema,
1114
+ mouseDownSchema,
1115
+ mouseUpSchema,
1116
+ bringToFrontSchema,
1117
+ waitForFunctionSchema,
1118
+ scrollIntoViewSchema,
1119
+ addInitScriptSchema,
1120
+ keyDownSchema,
1121
+ keyUpSchema,
1122
+ insertTextSchema,
1123
+ multiSelectSchema,
1124
+ waitForDownloadSchema,
1125
+ responseBodySchema,
1126
+ screencastStartSchema,
1127
+ screencastStopSchema,
1128
+ inputMouseSchema,
1129
+ inputKeyboardSchema,
1130
+ inputTouchSchema,
1131
+ swipeSchema,
1132
+ deviceListSchema,
1133
+ diffSnapshotSchema,
1134
+ diffScreenshotSchema,
1135
+ diffUrlSchema,
1136
+ confirmSchema,
1137
+ denySchema,
1138
+ authSaveSchema,
1139
+ authLoginSchema,
1140
+ authListSchema,
1141
+ authDeleteSchema,
1142
+ authShowSchema,
1143
+ // Nstbrowser commands
1144
+ nstBrowserListSchema,
1145
+ nstBrowserStartSchema,
1146
+ nstBrowserStopSchema,
1147
+ nstBrowserStopAllSchema,
1148
+ nstProfileListSchema,
1149
+ nstProfileCreateSchema,
1150
+ nstProfileDeleteSchema,
1151
+ nstProfileProxyUpdateSchema,
1152
+ nstProfileProxyResetSchema,
1153
+ nstProfileTagsListSchema,
1154
+ nstProfileTagsCreateSchema,
1155
+ nstProfileTagsClearSchema,
1156
+ nstProfileGroupsListSchema,
1157
+ nstProfileGroupChangeSchema,
1158
+ nstProfileCacheClearSchema,
1159
+ nstProfileCookiesClearSchema,
1160
+ nstProfileShowSchema,
1161
+ nstProfileProxyShowSchema,
1162
+ nstBrowserPagesSchema,
1163
+ nstBrowserDebuggerSchema,
1164
+ nstProfileTagsUpdateSchema,
1165
+ nstProfileProxyBatchUpdateSchema,
1166
+ nstProfileProxyBatchResetSchema,
1167
+ nstProfileTagsBatchCreateSchema,
1168
+ nstProfileTagsBatchUpdateSchema,
1169
+ nstProfileTagsBatchClearSchema,
1170
+ nstProfileGroupBatchChangeSchema,
1171
+ // New commands - Batch operations and CDP endpoints
1172
+ nstBrowserStartBatchSchema,
1173
+ nstBrowserStartOnceSchema,
1174
+ nstProfileListCursorSchema,
1175
+ nstBrowserConnectSchema,
1176
+ nstBrowserConnectOnceSchema,
1177
+ nstBrowserCdpUrlSchema,
1178
+ nstBrowserCdpUrlOnceSchema,
1179
+ ]);
1180
+ /**
1181
+ * Parse a JSON string into a validated command
1182
+ */
1183
+ export function parseCommand(input) {
1184
+ // First, try to parse JSON
1185
+ let json;
1186
+ try {
1187
+ json = JSON.parse(input);
1188
+ }
1189
+ catch {
1190
+ return { success: false, error: 'Invalid JSON' };
1191
+ }
1192
+ // Extract id for error responses if possible
1193
+ const id = typeof json === 'object' && json !== null && 'id' in json
1194
+ ? String(json.id)
1195
+ : undefined;
1196
+ // Validate against schema
1197
+ const result = commandSchema.safeParse(json);
1198
+ if (!result.success) {
1199
+ const errors = result.error.errors.map((e) => `${e.path.join('.')}: ${e.message}`).join(', ');
1200
+ return { success: false, error: `Validation error: ${errors}`, id };
1201
+ }
1202
+ const command = result.data;
1203
+ // Post-parse validation for commands that need cross-field checks
1204
+ if ((command.action === 'addscript' || command.action === 'addstyle') &&
1205
+ !command.content &&
1206
+ !command.url) {
1207
+ return { success: false, error: 'Either content or url must be provided', id };
1208
+ }
1209
+ if (command.action === 'frame' && !command.selector && !command.name && !command.url) {
1210
+ return {
1211
+ success: false,
1212
+ error: 'frame command requires at least one of: selector, name, or url',
1213
+ id,
1214
+ };
1215
+ }
1216
+ if (command.action === 'keyboard') {
1217
+ const sub = command.subaction ?? 'press';
1218
+ if ((sub === 'type' || sub === 'insertText') && !command.text) {
1219
+ return { success: false, error: `keyboard ${sub} requires text`, id };
1220
+ }
1221
+ if (sub === 'press' && !command.keys) {
1222
+ return { success: false, error: 'keyboard press requires keys', id };
1223
+ }
1224
+ }
1225
+ return { success: true, command };
1226
+ }
1227
+ /**
1228
+ * Create a success response
1229
+ */
1230
+ export function successResponse(id, data) {
1231
+ return { id, success: true, data };
1232
+ }
1233
+ /**
1234
+ * Create an error response
1235
+ */
1236
+ export function errorResponse(id, error) {
1237
+ return { id, success: false, error };
1238
+ }
1239
+ /**
1240
+ * Serialize a response to JSON string
1241
+ */
1242
+ export function serializeResponse(response) {
1243
+ return JSON.stringify(response);
1244
+ }
1245
+ //# sourceMappingURL=protocol.js.map