web-agent-bridge 1.1.2 → 2.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -21
- package/README.ar.md +446 -446
- package/README.md +780 -844
- package/bin/cli.js +80 -80
- package/bin/wab.js +80 -80
- package/examples/bidi-agent.js +119 -119
- package/examples/mcp-agent.js +94 -94
- package/examples/next-app-router/README.md +44 -0
- package/examples/puppeteer-agent.js +108 -108
- package/examples/saas-dashboard/README.md +55 -0
- package/examples/shopify-hydrogen/README.md +74 -0
- package/examples/vision-agent.js +171 -171
- package/examples/wordpress-elementor/README.md +77 -0
- package/package.json +69 -78
- package/public/.well-known/ai-assets.json +59 -0
- package/public/admin/login.html +84 -84
- package/public/ai.html +196 -0
- package/public/cookies.html +208 -208
- package/public/css/premium.css +317 -0
- package/public/css/styles.css +1235 -1235
- package/public/dashboard.html +704 -704
- package/public/demo.html +259 -0
- package/public/docs.html +585 -585
- package/public/feed.xml +89 -0
- package/public/index.html +495 -332
- package/public/js/auth-nav.js +31 -31
- package/public/js/auth-redirect.js +12 -12
- package/public/js/cookie-consent.js +56 -56
- package/public/js/wab-demo-page.js +721 -0
- package/public/js/ws-client.js +74 -74
- package/public/llms-full.txt +309 -0
- package/public/llms.txt +85 -0
- package/public/login.html +83 -83
- package/public/openapi.json +580 -0
- package/public/premium-dashboard.html +2487 -0
- package/public/premium.html +791 -0
- package/public/privacy.html +295 -295
- package/public/register.html +103 -103
- package/public/robots.txt +87 -0
- package/public/script/wab-consent.d.ts +36 -0
- package/public/script/wab-consent.js +104 -0
- package/public/script/wab-schema.js +131 -0
- package/public/script/wab.d.ts +108 -0
- package/public/script/wab.min.js +234 -0
- package/public/sitemap.xml +93 -0
- package/public/terms.html +254 -254
- package/public/video/tutorial.mp4 +0 -0
- package/script/ai-agent-bridge.js +1558 -1513
- package/sdk/README.md +55 -55
- package/sdk/index.d.ts +118 -0
- package/sdk/index.js +257 -203
- package/sdk/package.json +14 -14
- package/sdk/schema-discovery.js +83 -0
- package/server/config/secrets.js +94 -92
- package/server/index.js +0 -9
- package/server/middleware/adminAuth.js +30 -30
- package/server/middleware/auth.js +41 -41
- package/server/middleware/rateLimits.js +24 -24
- package/server/migrations/001_add_analytics_indexes.sql +7 -7
- package/server/migrations/002_premium_features.sql +418 -0
- package/server/models/adapters/index.js +33 -33
- package/server/models/adapters/mysql.js +183 -183
- package/server/models/adapters/postgresql.js +172 -172
- package/server/models/adapters/sqlite.js +7 -7
- package/server/models/db.js +561 -561
- package/server/routes/admin-premium.js +671 -0
- package/server/routes/admin.js +247 -247
- package/server/routes/api.js +131 -138
- package/server/routes/auth.js +51 -51
- package/server/routes/billing.js +45 -45
- package/server/routes/discovery.js +406 -329
- package/server/routes/license.js +240 -240
- package/server/routes/noscript.js +543 -543
- package/server/routes/premium-v2.js +686 -0
- package/server/routes/premium.js +724 -0
- package/server/routes/wab-api.js +476 -476
- package/server/services/agent-memory.js +625 -0
- package/server/services/email.js +204 -204
- package/server/services/fairness.js +420 -420
- package/server/services/plugins.js +747 -0
- package/server/services/premium.js +1883 -0
- package/server/services/self-healing.js +843 -0
- package/server/services/stripe.js +192 -192
- package/server/services/swarm.js +788 -0
- package/server/services/vision.js +871 -0
- package/server/utils/cache.js +125 -125
- package/server/utils/migrate.js +81 -81
- package/server/utils/secureFields.js +50 -50
- package/server/ws.js +101 -101
- package/docs/DEPLOY.md +0 -118
- package/docs/SPEC.md +0 -1540
- package/wab-mcp-adapter/README.md +0 -136
- package/wab-mcp-adapter/index.js +0 -555
- package/wab-mcp-adapter/package.json +0 -17
package/README.md
CHANGED
|
@@ -1,844 +1,780 @@
|
|
|
1
|
-
# Web Agent Bridge (WAB)
|
|
2
|
-
|
|
3
|
-
[](https://www.npmjs.com/package/web-agent-bridge)
|
|
4
|
-
[](https://github.com/abokenan444/web-agent-bridge/actions/workflows/ci.yml)
|
|
5
|
-
[](https://opensource.org/licenses/MIT)
|
|
6
|
-
[](https://nodejs.org/)
|
|
7
|
-
[](https://hub.docker.com/)
|
|
8
|
-
[](CONTRIBUTING.md)
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
- **
|
|
48
|
-
- **
|
|
49
|
-
- **
|
|
50
|
-
- **
|
|
51
|
-
- **
|
|
52
|
-
- **
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
---
|
|
117
|
-
|
|
118
|
-
##
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
#
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
#
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
|
257
|
-
|
|
258
|
-
|
|
|
259
|
-
|
|
|
260
|
-
|
|
|
261
|
-
|
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
|
378
|
-
|
|
379
|
-
|
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
},
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
|
|
458
|
-
|
|
459
|
-
|
|
460
|
-
|
|
461
|
-
|
|
462
|
-
|
|
463
|
-
|
|
464
|
-
|
|
465
|
-
|
|
466
|
-
|
|
467
|
-
|
|
468
|
-
|
|
469
|
-
|
|
470
|
-
|
|
471
|
-
|
|
472
|
-
|
|
473
|
-
|
|
474
|
-
|
|
475
|
-
|
|
476
|
-
|
|
477
|
-
|
|
478
|
-
|
|
479
|
-
|
|
480
|
-
|
|
481
|
-
|
|
482
|
-
|
|
483
|
-
|
|
484
|
-
|
|
485
|
-
|
|
486
|
-
|
|
487
|
-
|
|
488
|
-
|
|
489
|
-
|
|
490
|
-
|
|
491
|
-
|
|
492
|
-
|
|
493
|
-
|
|
494
|
-
|
|
495
|
-
}
|
|
496
|
-
|
|
497
|
-
|
|
498
|
-
|
|
499
|
-
|
|
500
|
-
```
|
|
501
|
-
|
|
502
|
-
|
|
503
|
-
|
|
504
|
-
|
|
505
|
-
|
|
506
|
-
|
|
507
|
-
|
|
508
|
-
|
|
509
|
-
//
|
|
510
|
-
|
|
511
|
-
|
|
512
|
-
|
|
513
|
-
|
|
514
|
-
|
|
515
|
-
|
|
516
|
-
|
|
517
|
-
|
|
518
|
-
|
|
519
|
-
|
|
520
|
-
const
|
|
521
|
-
|
|
522
|
-
|
|
523
|
-
```
|
|
524
|
-
|
|
525
|
-
|
|
526
|
-
|
|
527
|
-
|
|
528
|
-
|
|
529
|
-
|
|
530
|
-
|
|
531
|
-
|
|
532
|
-
|
|
533
|
-
|
|
534
|
-
|
|
535
|
-
|
|
536
|
-
|
|
537
|
-
|
|
538
|
-
|
|
539
|
-
|
|
540
|
-
|
|
541
|
-
|
|
542
|
-
|
|
543
|
-
|
|
544
|
-
|
|
545
|
-
|
|
546
|
-
|
|
547
|
-
|
|
548
|
-
|
|
549
|
-
//
|
|
550
|
-
|
|
551
|
-
|
|
552
|
-
|
|
553
|
-
|
|
554
|
-
|
|
555
|
-
|
|
556
|
-
|
|
557
|
-
|
|
558
|
-
|
|
559
|
-
|
|
560
|
-
|
|
561
|
-
|
|
562
|
-
|
|
563
|
-
|
|
564
|
-
|
|
565
|
-
|
|
566
|
-
|
|
567
|
-
|
|
568
|
-
|
|
569
|
-
|
|
570
|
-
|
|
571
|
-
|
|
572
|
-
|
|
573
|
-
|
|
574
|
-
|
|
575
|
-
|
|
576
|
-
|
|
577
|
-
|
|
578
|
-
|
|
579
|
-
|
|
580
|
-
|
|
581
|
-
|
|
582
|
-
|
|
583
|
-
|
|
584
|
-
|
|
585
|
-
|
|
586
|
-
|
|
587
|
-
|
|
588
|
-
|
|
589
|
-
|
|
590
|
-
|
|
591
|
-
|
|
592
|
-
|
|
593
|
-
|
|
594
|
-
|
|
595
|
-
|
|
596
|
-
|
|
597
|
-
|
|
598
|
-
|
|
599
|
-
|
|
600
|
-
|
|
601
|
-
|
|
602
|
-
|
|
603
|
-
|
|
604
|
-
|
|
605
|
-
|
|
606
|
-
|
|
607
|
-
|
|
608
|
-
|
|
609
|
-
|
|
610
|
-
|
|
611
|
-
|
|
612
|
-
|
|
613
|
-
|
|
614
|
-
|
|
615
|
-
|
|
616
|
-
|
|
617
|
-
|
|
618
|
-
|
|
619
|
-
|
|
620
|
-
|
|
621
|
-
|
|
622
|
-
|
|
623
|
-
|
|
624
|
-
|
|
625
|
-
|
|
626
|
-
|
|
627
|
-
|
|
628
|
-
|
|
629
|
-
|
|
630
|
-
|
|
631
|
-
|
|
632
|
-
|
|
633
|
-
|
|
634
|
-
|
|
635
|
-
|
|
636
|
-
|
|
637
|
-
|
|
638
|
-
|
|
639
|
-
|
|
640
|
-
|
|
641
|
-
|
|
642
|
-
|
|
643
|
-
|
|
644
|
-
|
|
645
|
-
|
|
646
|
-
|
|
647
|
-
|
|
648
|
-
|
|
649
|
-
|
|
650
|
-
|
|
651
|
-
|
|
652
|
-
|
|
653
|
-
|
|
654
|
-
|
|
655
|
-
|
|
656
|
-
|
|
657
|
-
|
|
658
|
-
|
|
659
|
-
|
|
660
|
-
|
|
661
|
-
|
|
662
|
-
|
|
663
|
-
|
|
664
|
-
|
|
665
|
-
|
|
666
|
-
|
|
667
|
-
|
|
668
|
-
|
|
669
|
-
|
|
670
|
-
|
|
671
|
-
|
|
672
|
-
|
|
673
|
-
|
|
674
|
-
|
|
675
|
-
|
|
676
|
-
|
|
677
|
-
|
|
678
|
-
|
|
679
|
-
|
|
680
|
-
|
|
681
|
-
|
|
682
|
-
|
|
683
|
-
|
|
684
|
-
|
|
685
|
-
|
|
686
|
-
3. **
|
|
687
|
-
|
|
688
|
-
|
|
689
|
-
|
|
690
|
-
|
|
691
|
-
|
|
692
|
-
|
|
693
|
-
|
|
694
|
-
|
|
695
|
-
|
|
696
|
-
|
|
697
|
-
|
|
698
|
-
|
|
699
|
-
|
|
700
|
-
|
|
701
|
-
|
|
702
|
-
|
|
703
|
-
|
|
704
|
-
|
|
705
|
-
-
|
|
706
|
-
-
|
|
707
|
-
|
|
708
|
-
|
|
709
|
-
|
|
710
|
-
|
|
711
|
-
|
|
712
|
-
|
|
713
|
-
|
|
714
|
-
|
|
715
|
-
|
|
716
|
-
|
|
717
|
-
|
|
718
|
-
|
|
719
|
-
|
|
720
|
-
|
|
721
|
-
|
|
722
|
-
|
|
723
|
-
|
|
724
|
-
|
|
725
|
-
|
|
726
|
-
|
|
727
|
-
|
|
728
|
-
|
|
729
|
-
|
|
730
|
-
|
|
731
|
-
|
|
732
|
-
|
|
733
|
-
|
|
734
|
-
|
|
735
|
-
|
|
736
|
-
|
|
737
|
-
|
|
738
|
-
|
|
739
|
-
|
|
740
|
-
|
|
741
|
-
|
|
742
|
-
|
|
743
|
-
|
|
744
|
-
|
|
745
|
-
|
|
746
|
-
|
|
747
|
-
|
|
748
|
-
|
|
749
|
-
|
|
750
|
-
|
|
751
|
-
|
|
752
|
-
|
|
753
|
-
|
|
754
|
-
|
|
755
|
-
|
|
756
|
-
|
|
757
|
-
|
|
758
|
-
|
|
759
|
-
|
|
760
|
-
|
|
761
|
-
|
|
762
|
-
```
|
|
763
|
-
|
|
764
|
-
|
|
765
|
-
|
|
766
|
-
|
|
767
|
-
|
|
768
|
-
|
|
769
|
-
|
|
770
|
-
|
|
771
|
-
|
|
772
|
-
|
|
773
|
-
|
|
774
|
-
|
|
775
|
-
|
|
776
|
-
|
|
777
|
-
|
|
778
|
-
|
|
779
|
-
|
|
780
|
-
|
|
781
|
-
stealth: {
|
|
782
|
-
enabled: true,
|
|
783
|
-
consent: true // Required — confirms site owner authorizes human-like patterns
|
|
784
|
-
}
|
|
785
|
-
};
|
|
786
|
-
```
|
|
787
|
-
|
|
788
|
-
> **⚠️ Ethical Use Policy:** Stealth mode is designed for accessibility and testing on your own websites. Using it to bypass security controls on sites you do not own may violate terms of service and applicable laws.
|
|
789
|
-
|
|
790
|
-
When enabled, all interactions use:
|
|
791
|
-
|
|
792
|
-
| Feature | Description |
|
|
793
|
-
|---|---|
|
|
794
|
-
| **Mouse event chain** | `mouseover → mouseenter → mousemove → mousedown → mouseup → click` with natural coordinates |
|
|
795
|
-
| **Typing simulation** | Character-by-character input with 30-120ms delays per keystroke |
|
|
796
|
-
| **Scroll easing** | Multi-step scrolling with variable speed |
|
|
797
|
-
| **Random delays** | 50-400ms natural pauses between actions |
|
|
798
|
-
|
|
799
|
-
```javascript
|
|
800
|
-
// Enable/disable at runtime (consent required)
|
|
801
|
-
bridge.stealth.enable(true); // true = consent granted
|
|
802
|
-
bridge.stealth.disable();
|
|
803
|
-
```
|
|
804
|
-
|
|
805
|
-
---
|
|
806
|
-
|
|
807
|
-
## CLI
|
|
808
|
-
|
|
809
|
-
Install globally or use via npx:
|
|
810
|
-
|
|
811
|
-
```bash
|
|
812
|
-
# Run the server
|
|
813
|
-
npx web-agent-bridge start
|
|
814
|
-
npx web-agent-bridge start --port 8080
|
|
815
|
-
|
|
816
|
-
# Initialize a new project
|
|
817
|
-
npx web-agent-bridge init
|
|
818
|
-
```
|
|
819
|
-
|
|
820
|
-
---
|
|
821
|
-
|
|
822
|
-
## Environment Variables
|
|
823
|
-
|
|
824
|
-
See `.env.example`. Important:
|
|
825
|
-
|
|
826
|
-
```
|
|
827
|
-
PORT=3000
|
|
828
|
-
NODE_ENV=development
|
|
829
|
-
JWT_SECRET=long-random-user-signing-secret
|
|
830
|
-
JWT_SECRET_ADMIN=long-random-admin-signing-secret # required in production
|
|
831
|
-
ALLOWED_ORIGINS=http://localhost:3000,https://your-app.com
|
|
832
|
-
STRIPE_WEBHOOK_SECRET=whsec_... # Stripe webhook verify
|
|
833
|
-
CREDENTIALS_ENCRYPTION_KEY=... # optional SMTP password encryption
|
|
834
|
-
DB_ADAPTER=sqlite
|
|
835
|
-
DATABASE_URL=
|
|
836
|
-
```
|
|
837
|
-
|
|
838
|
-
First admin: set `BOOTSTRAP_ADMIN_EMAIL` / `BOOTSTRAP_ADMIN_PASSWORD` when the `admins` table is empty, or run `node scripts/create-admin.js <email> <password>`.
|
|
839
|
-
|
|
840
|
-
---
|
|
841
|
-
|
|
842
|
-
## License
|
|
843
|
-
|
|
844
|
-
MIT — Free to use, modify, and distribute.
|
|
1
|
+
# Web Agent Bridge (WAB)
|
|
2
|
+
|
|
3
|
+
[](https://www.npmjs.com/package/web-agent-bridge)
|
|
4
|
+
[](https://github.com/abokenan444/web-agent-bridge/actions/workflows/ci.yml)
|
|
5
|
+
[](https://opensource.org/licenses/MIT)
|
|
6
|
+
[](https://nodejs.org/)
|
|
7
|
+
[](https://hub.docker.com/)
|
|
8
|
+
[](CONTRIBUTING.md)
|
|
9
|
+
|
|
10
|
+
> **robots.txt told bots what NOT to do. WAB tells AI agents what they CAN do.**
|
|
11
|
+
|
|
12
|
+
**English** | **[العربية](README.ar.md)**
|
|
13
|
+
|
|
14
|
+
WAB is an open-source middleware layer that bridges AI agents and websites — like **OpenAPI for human-facing pages**. Website owners embed a script that exposes a standardized `window.AICommands` interface. AI agents discover available actions, execute commands, and interact with sites accurately — no DOM parsing, no scraping, no guesswork.
|
|
15
|
+
|
|
16
|
+
### Three Paths to WAB
|
|
17
|
+
|
|
18
|
+
| Path | For | How |
|
|
19
|
+
|---|---|---|
|
|
20
|
+
| **🏢 Website Owner** | Control how AI interacts with your site | Embed the script, configure permissions |
|
|
21
|
+
| **🤖 Agent Developer** | Build reliable agents that work on any WAB-enabled site | Use `window.AICommands` or the Agent SDK |
|
|
22
|
+
| **🔧 Self-Hosting** | Run the full WAB platform for your organization | Clone, deploy, manage licenses & analytics |
|
|
23
|
+
| **WordPress** | Sites powered by WP | Use the **[Web Agent Bridge WordPress plugin](web-agent-bridge-wordpress/README.md)** (settings, shortcode, per-page disable, hooks) |
|
|
24
|
+
|
|
25
|
+
---
|
|
26
|
+
|
|
27
|
+
## Features
|
|
28
|
+
|
|
29
|
+
- **Auto-Discovery** — Automatically detects buttons, forms, and navigation on the page
|
|
30
|
+
- **Structured Auto-Discovery** — Detects schema.org JSON-LD + microdata products/offers and exposes read actions
|
|
31
|
+
- **Commerce + Booking Intents** — Detects common actions like add-to-cart, checkout, and booking/reservation flows
|
|
32
|
+
- **Permission System** — Granular control over what AI agents can do (click, fill forms, API access, etc.)
|
|
33
|
+
- **Standardized Interface** — Unified `window.AICommands` object any agent can consume
|
|
34
|
+
- **Secure License Exchange** — Embed uses public `siteId` + `/api/license/token`; long-lived license keys stay in the owner dashboard, not in HTML
|
|
35
|
+
- **Rate Limiting** — Multi-dimensional abuse protection (IP + license key + site)
|
|
36
|
+
- **Analytics Dashboard** — Track how AI agents interact with your site
|
|
37
|
+
- **Real-Time Analytics** — WebSocket-based live event streaming with auto-reconnection
|
|
38
|
+
- **In-Memory Caching** — TTL-based cache layer reduces DB reads on hot paths
|
|
39
|
+
- **Analytics Queue** — Batched writes with transaction support for high-throughput tracking
|
|
40
|
+
- **WebDriver BiDi Compatible** — Standard protocol support via `window.__wab_bidi`
|
|
41
|
+
- **CDN Versioning** — Serve scripts via versioned URLs (`/v1/ai-agent-bridge.js`, `/latest/ai-agent-bridge.js`)
|
|
42
|
+
- **Docker Ready** — One-command deployment with Docker Compose
|
|
43
|
+
- **DB Migrations** — Numbered SQL migration runner with tracking table
|
|
44
|
+
- **Custom Actions** — Register your own actions with custom handlers
|
|
45
|
+
- **Subscription Tiers** — Free core + paid premium features (API access, analytics, automated login)
|
|
46
|
+
- **Event System** — Subscribe to bridge events for monitoring
|
|
47
|
+
- **Security Sandbox** — Origin validation, session tokens, command signing, audit logging, auto-lockdown
|
|
48
|
+
- **Self-Healing Selectors** — Resilient element resolution with fuzzy matching for dynamic SPAs
|
|
49
|
+
- **Stealth Mode** — Human-like interaction patterns (requires explicit consent)
|
|
50
|
+
- **Multi-Database** — SQLite (default), PostgreSQL, MySQL via pluggable adapters
|
|
51
|
+
- **Agent SDK** — Built-in SDK for building AI agents with Puppeteer/Playwright
|
|
52
|
+
- **React Package** — `@web-agent-bridge/react` with `WABProvider`, `useWAB`, `useWABAction`, and `useWABActions`
|
|
53
|
+
- **Vue Package** — `@web-agent-bridge/vue` composables (`useWAB`, `useWABAction`, `useWABActions`) for Vue 3+
|
|
54
|
+
- **Svelte Package** — `@web-agent-bridge/svelte` stores (`createWAB`, `createWABAction`) for Svelte 3+
|
|
55
|
+
- **LangChain Adapter** — `@web-agent-bridge/langchain` wraps WAB actions as LangChain tools for LLM agents
|
|
56
|
+
- **GDPR/CCPA Consent** — Optional `wab-consent.js` banner with `WABConsent.showBanner()` and `hasConsent()` gate
|
|
57
|
+
- **Admin Dashboard** — User management, tier grants, system analytics
|
|
58
|
+
- **Stripe Integration** — Payment processing with customer portal
|
|
59
|
+
|
|
60
|
+
---
|
|
61
|
+
|
|
62
|
+
## Quick Start
|
|
63
|
+
|
|
64
|
+
### 1. Install & Run the Server
|
|
65
|
+
|
|
66
|
+
```bash
|
|
67
|
+
# Option A: Clone and run
|
|
68
|
+
git clone https://github.com/abokenan444/web-agent-bridge.git
|
|
69
|
+
cd web-agent-bridge
|
|
70
|
+
npm install
|
|
71
|
+
cp .env.example .env
|
|
72
|
+
npm start
|
|
73
|
+
|
|
74
|
+
# Option B: npx (one command)
|
|
75
|
+
npx web-agent-bridge start
|
|
76
|
+
|
|
77
|
+
# Option C: Docker
|
|
78
|
+
docker compose up -d
|
|
79
|
+
```
|
|
80
|
+
|
|
81
|
+
### 2. Create an Account
|
|
82
|
+
|
|
83
|
+
Visit `http://localhost:3000/register` and create an account, then add your site from the dashboard.
|
|
84
|
+
|
|
85
|
+
### 3. Add the Script to Your Website
|
|
86
|
+
|
|
87
|
+
```html
|
|
88
|
+
<!-- Recommended: copy the snippet from your dashboard (uses siteId only) -->
|
|
89
|
+
<script>
|
|
90
|
+
window.AIBridgeConfig = {
|
|
91
|
+
siteId: "your-site-uuid-from-dashboard",
|
|
92
|
+
configEndpoint: "https://yourserver.com/api/license/token",
|
|
93
|
+
agentPermissions: {
|
|
94
|
+
readContent: true,
|
|
95
|
+
click: true,
|
|
96
|
+
fillForms: true,
|
|
97
|
+
scroll: true
|
|
98
|
+
}
|
|
99
|
+
};
|
|
100
|
+
</script>
|
|
101
|
+
<script src="https://yourserver.com/script/ai-agent-bridge.js"></script>
|
|
102
|
+
```
|
|
103
|
+
|
|
104
|
+
The server matches **Origin** to your registered site domain, then returns a short-lived **session token**. Analytics (`/api/license/track`) require that session — not the long-lived license key. Keep the license key in the dashboard only.
|
|
105
|
+
|
|
106
|
+
### 4. AI Agents Can Now Interact
|
|
107
|
+
|
|
108
|
+
```javascript
|
|
109
|
+
// From the AI agent's side
|
|
110
|
+
const bridge = window.AICommands;
|
|
111
|
+
const actions = bridge.getActions(); // discover actions
|
|
112
|
+
await bridge.execute("signup"); // execute an action
|
|
113
|
+
const info = bridge.getPageInfo(); // get page metadata
|
|
114
|
+
```
|
|
115
|
+
|
|
116
|
+
---
|
|
117
|
+
|
|
118
|
+
## Project Structure
|
|
119
|
+
|
|
120
|
+
```
|
|
121
|
+
web-agent-bridge/
|
|
122
|
+
├── server/ # Express.js backend
|
|
123
|
+
│ ├── index.js # Server entry point
|
|
124
|
+
│ ├── routes/
|
|
125
|
+
│ │ ├── auth.js # Authentication (register/login)
|
|
126
|
+
│ │ ├── api.js # Sites, config, analytics API
|
|
127
|
+
│ │ ├── license.js # License verification, token exchange & tracking
|
|
128
|
+
│ │ ├── admin.js # Admin dashboard API
|
|
129
|
+
│ │ └── billing.js # Stripe billing integration
|
|
130
|
+
│ ├── middleware/
|
|
131
|
+
│ │ └── auth.js # JWT authentication middleware
|
|
132
|
+
│ ├── models/
|
|
133
|
+
│ │ └── db.js # SQLite database & operations
|
|
134
|
+
│ ├── migrations/ # Numbered SQL migrations
|
|
135
|
+
│ └── utils/
|
|
136
|
+
│ ├── cache.js # In-memory cache + analytics queue
|
|
137
|
+
│ └── migrate.js # Migration runner
|
|
138
|
+
├── public/ # Frontend
|
|
139
|
+
│ ├── index.html # Landing page
|
|
140
|
+
│ ├── dashboard.html # Management dashboard
|
|
141
|
+
│ ├── docs.html # Documentation
|
|
142
|
+
│ ├── login.html # Sign in
|
|
143
|
+
│ ├── register.html # Sign up
|
|
144
|
+
│ ├── admin/ # Admin panel
|
|
145
|
+
│ ├── js/
|
|
146
|
+
│ │ └── ws-client.js # WebSocket client with auto-reconnect
|
|
147
|
+
│ └── css/styles.css # Design system
|
|
148
|
+
├── script/
|
|
149
|
+
│ └── ai-agent-bridge.js # The bridge script (embed in websites)
|
|
150
|
+
├── examples/ # Agent examples (Puppeteer, BiDi, Vision)
|
|
151
|
+
├── packages/ # Framework wrappers
|
|
152
|
+
│ ├── react/ # @web-agent-bridge/react
|
|
153
|
+
│ ├── vue/ # @web-agent-bridge/vue
|
|
154
|
+
│ ├── svelte/ # @web-agent-bridge/svelte
|
|
155
|
+
│ └── langchain/ # @web-agent-bridge/langchain
|
|
156
|
+
├── sdk/ # Agent SDK for Puppeteer/Playwright
|
|
157
|
+
├── .env # Environment variables
|
|
158
|
+
└── package.json
|
|
159
|
+
```
|
|
160
|
+
|
|
161
|
+
---
|
|
162
|
+
|
|
163
|
+
## API Endpoints
|
|
164
|
+
|
|
165
|
+
### Authentication
|
|
166
|
+
| Endpoint | Method | Description |
|
|
167
|
+
|---|---|---|
|
|
168
|
+
| `/api/auth/register` | POST | Create account |
|
|
169
|
+
| `/api/auth/login` | POST | Sign in, receive JWT |
|
|
170
|
+
| `/api/auth/me` | GET | Get current user |
|
|
171
|
+
|
|
172
|
+
### Sites
|
|
173
|
+
| Endpoint | Method | Description |
|
|
174
|
+
|---|---|---|
|
|
175
|
+
| `/api/sites` | GET | List your sites |
|
|
176
|
+
| `/api/sites` | POST | Add a new site |
|
|
177
|
+
| `/api/sites/:id` | GET | Get site details |
|
|
178
|
+
| `/api/sites/:id/config` | PUT | Update configuration |
|
|
179
|
+
| `/api/sites/:id/tier` | PUT | Change subscription tier |
|
|
180
|
+
| `/api/sites/:id` | DELETE | Delete a site |
|
|
181
|
+
| `/api/sites/:id/snippet` | GET | Get install code snippet |
|
|
182
|
+
| `/api/sites/:id/analytics` | GET | Get analytics data |
|
|
183
|
+
|
|
184
|
+
### License (Public)
|
|
185
|
+
| Endpoint | Method | Description |
|
|
186
|
+
|---|---|---|
|
|
187
|
+
| `/api/license/verify` | POST | Verify license key for domain (cached) |
|
|
188
|
+
| `/api/license/token` | POST | Exchange `siteId` (Origin must match domain) or `licenseKey` for session token |
|
|
189
|
+
| `/api/license/session` | POST | Validate session token (domain-locked) |
|
|
190
|
+
| `/api/license/track` | POST | Record analytics (`sessionToken` + Origin; legacy `licenseKey` only if `ALLOW_LEGACY_LICENSE_TRACK`) |
|
|
191
|
+
|
|
192
|
+
---
|
|
193
|
+
|
|
194
|
+
## Bridge Script API
|
|
195
|
+
|
|
196
|
+
Once loaded, `window.AICommands` exposes:
|
|
197
|
+
|
|
198
|
+
| Method | Description |
|
|
199
|
+
|---|---|
|
|
200
|
+
| `getActions(category?)` | List available actions |
|
|
201
|
+
| `getAction(name)` | Get a specific action |
|
|
202
|
+
| `execute(name, params?)` | Execute an action |
|
|
203
|
+
| `readContent(selector)` | Read element content |
|
|
204
|
+
| `getPageInfo()` | Get page and bridge metadata |
|
|
205
|
+
| `waitForElement(selector, timeout?)` | Wait for DOM element |
|
|
206
|
+
| `waitForNavigation(timeout?)` | Wait for URL change |
|
|
207
|
+
| `registerAction(def)` | Register a custom action |
|
|
208
|
+
| `authenticate(key, meta?)` | Authenticate an agent |
|
|
209
|
+
| `refresh()` | Re-scan the page |
|
|
210
|
+
| `onReady(callback)` | Callback when bridge is ready |
|
|
211
|
+
| `events.on(event, cb)` | Subscribe to events |
|
|
212
|
+
|
|
213
|
+
---
|
|
214
|
+
|
|
215
|
+
## Configuration
|
|
216
|
+
|
|
217
|
+
```javascript
|
|
218
|
+
window.AIBridgeConfig = {
|
|
219
|
+
// Recommended — copy siteId from dashboard snippet (no license key in HTML)
|
|
220
|
+
siteId: "uuid-from-dashboard",
|
|
221
|
+
configEndpoint: "/api/license/token",
|
|
222
|
+
|
|
223
|
+
// Legacy: token exchange via license key (avoid embedding in public pages)
|
|
224
|
+
// licenseKey: "WAB-...",
|
|
225
|
+
|
|
226
|
+
agentPermissions: {
|
|
227
|
+
readContent: true, // Read page text
|
|
228
|
+
click: true, // Click elements
|
|
229
|
+
fillForms: false, // Fill/submit forms
|
|
230
|
+
scroll: true, // Scroll page
|
|
231
|
+
navigate: false, // Navigate pages
|
|
232
|
+
apiAccess: false, // Internal API calls (Pro+)
|
|
233
|
+
automatedLogin: false, // Auto login (Starter+)
|
|
234
|
+
extractData: false // Data extraction (Pro+)
|
|
235
|
+
},
|
|
236
|
+
restrictions: {
|
|
237
|
+
allowedSelectors: [],
|
|
238
|
+
blockedSelectors: [".private", "[data-private]"],
|
|
239
|
+
requireLoginForActions: ["apiAccess"],
|
|
240
|
+
rateLimit: { maxCallsPerMinute: 60 }
|
|
241
|
+
},
|
|
242
|
+
logging: { enabled: false, level: "basic" }
|
|
243
|
+
};
|
|
244
|
+
```
|
|
245
|
+
|
|
246
|
+
---
|
|
247
|
+
|
|
248
|
+
## Subscription Tiers
|
|
249
|
+
|
|
250
|
+
| Feature | Free | Starter | Pro | Enterprise |
|
|
251
|
+
|---|:---:|:---:|:---:|:---:|
|
|
252
|
+
| Auto-discovery | ✓ | ✓ | ✓ | ✓ |
|
|
253
|
+
| Click/Scroll | ✓ | ✓ | ✓ | ✓ |
|
|
254
|
+
| Form filling | ✓ | ✓ | ✓ | ✓ |
|
|
255
|
+
| Basic logging | ✓ | ✓ | ✓ | ✓ |
|
|
256
|
+
| Automated login | ✗ | ✓ | ✓ | ✓ |
|
|
257
|
+
| Analytics dashboard | ✗ | ✓ | ✓ | ✓ |
|
|
258
|
+
| API access | ✗ | ✗ | ✓ | ✓ |
|
|
259
|
+
| Data extraction | ✗ | ✗ | ✓ | ✓ |
|
|
260
|
+
| Custom rate limits | ✗ | ✗ | ✗ | ✓ |
|
|
261
|
+
| Webhooks | ✗ | ✗ | ✗ | ✓ |
|
|
262
|
+
|
|
263
|
+
---
|
|
264
|
+
|
|
265
|
+
## Tech Stack
|
|
266
|
+
|
|
267
|
+
- **Backend**: Node.js + Express + WebSocket (ws)
|
|
268
|
+
- **Database**: SQLite (via better-sqlite3) with migration runner
|
|
269
|
+
- **Auth**: JWT + bcrypt + session tokens (domain-locked)
|
|
270
|
+
- **Caching**: In-memory TTL cache + batched analytics queue
|
|
271
|
+
- **Payments**: Stripe integration with billing portal
|
|
272
|
+
- **Frontend**: Vanilla HTML/CSS/JS (no framework dependencies)
|
|
273
|
+
- **Framework Wrappers**: React, Vue 3, Svelte (optional)
|
|
274
|
+
- **LLM Integration**: LangChain adapter, MCP adapter
|
|
275
|
+
- **Security**: Helmet, CORS, CSP, multi-layer rate limiting
|
|
276
|
+
- **Containers**: Docker + Docker Compose
|
|
277
|
+
- **CI/CD**: GitHub Actions (test + auto-publish to npm)
|
|
278
|
+
- **Testing**: Jest + Supertest
|
|
279
|
+
|
|
280
|
+
---
|
|
281
|
+
|
|
282
|
+
## WebDriver BiDi Compatibility
|
|
283
|
+
|
|
284
|
+
WAB exposes a `window.__wab_bidi` interface for agents using standardized WebDriver BiDi protocol:
|
|
285
|
+
|
|
286
|
+
```javascript
|
|
287
|
+
// Get BiDi context
|
|
288
|
+
const context = window.__wab_bidi.getContext();
|
|
289
|
+
|
|
290
|
+
// Send BiDi command
|
|
291
|
+
const result = await window.__wab_bidi.send({
|
|
292
|
+
id: 1,
|
|
293
|
+
method: 'wab.executeAction',
|
|
294
|
+
params: { name: 'signup', data: {} }
|
|
295
|
+
});
|
|
296
|
+
|
|
297
|
+
// Supported methods:
|
|
298
|
+
// wab.getContext, wab.getActions, wab.executeAction, wab.readContent, wab.getPageInfo
|
|
299
|
+
```
|
|
300
|
+
|
|
301
|
+
---
|
|
302
|
+
|
|
303
|
+
## Real-Time Analytics (WebSocket)
|
|
304
|
+
|
|
305
|
+
Connect to `ws://localhost:3000/ws/analytics` for live analytics. Use the built-in `WABWebSocket` client for automatic reconnection with exponential backoff:
|
|
306
|
+
|
|
307
|
+
```javascript
|
|
308
|
+
// Recommended: use the auto-reconnecting client
|
|
309
|
+
import { WABWebSocket } from './js/ws-client.js';
|
|
310
|
+
|
|
311
|
+
const ws = new WABWebSocket('jwt-token', 'site-id');
|
|
312
|
+
ws.on('analytic', (data) => console.log(data));
|
|
313
|
+
ws.on('reconnecting', ({ attempt, delay }) => console.log(`Reconnecting #${attempt}...`));
|
|
314
|
+
ws.connect();
|
|
315
|
+
```
|
|
316
|
+
|
|
317
|
+
```javascript
|
|
318
|
+
// Or connect manually
|
|
319
|
+
const ws = new WebSocket('ws://localhost:3000/ws/analytics');
|
|
320
|
+
ws.onopen = () => ws.send(JSON.stringify({ type: 'auth', token: 'jwt-token', siteId: 'site-id' }));
|
|
321
|
+
ws.onmessage = (e) => console.log(JSON.parse(e.data));
|
|
322
|
+
```
|
|
323
|
+
|
|
324
|
+
### WebSocket Message Protocol
|
|
325
|
+
|
|
326
|
+
**Client → Server Messages:**
|
|
327
|
+
|
|
328
|
+
| Message | Fields | Description |
|
|
329
|
+
|---|---|---|
|
|
330
|
+
| `auth` | `type`, `token`, `siteId` | Authenticate and subscribe to a site's events |
|
|
331
|
+
|
|
332
|
+
```json
|
|
333
|
+
{ "type": "auth", "token": "eyJhbGciOi...", "siteId": "uuid-of-site" }
|
|
334
|
+
```
|
|
335
|
+
|
|
336
|
+
**Server → Client Messages:**
|
|
337
|
+
|
|
338
|
+
| Message Type | Fields | Description |
|
|
339
|
+
|---|---|---|
|
|
340
|
+
| `auth:success` | `type`, `siteId` | Authentication succeeded |
|
|
341
|
+
| `analytic` | `type`, `timestamp`, `actionName`, `agentId`, `success` | Real-time analytics event |
|
|
342
|
+
| `error` | `type`, `message` | Error (invalid auth, malformed message) |
|
|
343
|
+
|
|
344
|
+
```json
|
|
345
|
+
// Success response
|
|
346
|
+
{ "type": "auth:success", "siteId": "uuid-of-site" }
|
|
347
|
+
|
|
348
|
+
// Analytics event
|
|
349
|
+
{
|
|
350
|
+
"type": "analytic",
|
|
351
|
+
"timestamp": "2024-01-15T10:30:00.000Z",
|
|
352
|
+
"actionName": "click-signup",
|
|
353
|
+
"agentId": "agent-123",
|
|
354
|
+
"triggerType": "click",
|
|
355
|
+
"success": true
|
|
356
|
+
}
|
|
357
|
+
|
|
358
|
+
// Error
|
|
359
|
+
{ "type": "error", "message": "Invalid message or auth failed" }
|
|
360
|
+
```
|
|
361
|
+
|
|
362
|
+
**Connection Lifecycle:**
|
|
363
|
+
1. Connect to `ws://host:port/ws/analytics`
|
|
364
|
+
2. Send `auth` message with valid JWT and site ID
|
|
365
|
+
3. Receive `auth:success` confirmation
|
|
366
|
+
4. Receive `analytic` events as they occur
|
|
367
|
+
5. Server sends heartbeat pings every 30 seconds — dead connections are cleaned up automatically
|
|
368
|
+
|
|
369
|
+
---
|
|
370
|
+
|
|
371
|
+
## CDN & Versioning
|
|
372
|
+
|
|
373
|
+
Scripts are served at versioned URLs for cache-safe deployments:
|
|
374
|
+
|
|
375
|
+
| URL | Description |
|
|
376
|
+
|---|---|
|
|
377
|
+
| `/script/ai-agent-bridge.js` | Default path |
|
|
378
|
+
| `/v1/ai-agent-bridge.js` | Version-pinned (recommended) |
|
|
379
|
+
| `/latest/ai-agent-bridge.js` | Always latest (use with caution) |
|
|
380
|
+
|
|
381
|
+
---
|
|
382
|
+
|
|
383
|
+
## Docker
|
|
384
|
+
|
|
385
|
+
```bash
|
|
386
|
+
# Quick start
|
|
387
|
+
docker compose up -d
|
|
388
|
+
|
|
389
|
+
# Or build manually
|
|
390
|
+
docker build -t web-agent-bridge .
|
|
391
|
+
docker run -p 3000:3000 -e JWT_SECRET=your-secret -e JWT_SECRET_ADMIN=your-admin-secret web-agent-bridge
|
|
392
|
+
```
|
|
393
|
+
|
|
394
|
+
---
|
|
395
|
+
|
|
396
|
+
## Testing
|
|
397
|
+
|
|
398
|
+
```bash
|
|
399
|
+
npm test
|
|
400
|
+
```
|
|
401
|
+
|
|
402
|
+
Tests cover: authentication, site CRUD, config management, license verification, analytics tracking, and static pages.
|
|
403
|
+
|
|
404
|
+
---
|
|
405
|
+
|
|
406
|
+
## Agent SDK
|
|
407
|
+
|
|
408
|
+
WAB includes a built-in SDK for building AI agents. See [`sdk/README.md`](sdk/README.md) for full documentation.
|
|
409
|
+
|
|
410
|
+
```javascript
|
|
411
|
+
const puppeteer = require('puppeteer');
|
|
412
|
+
const { WABAgent } = require('web-agent-bridge/sdk');
|
|
413
|
+
|
|
414
|
+
const browser = await puppeteer.launch();
|
|
415
|
+
const page = await browser.newPage();
|
|
416
|
+
const agent = new WABAgent(page);
|
|
417
|
+
|
|
418
|
+
await agent.navigateAndWait('https://example.com');
|
|
419
|
+
const actions = await agent.getActions();
|
|
420
|
+
await agent.execute('signup', { email: 'user@test.com' });
|
|
421
|
+
await browser.close();
|
|
422
|
+
```
|
|
423
|
+
|
|
424
|
+
### SDK Extras
|
|
425
|
+
|
|
426
|
+
The SDK now includes additional helpers for advanced agent workflows:
|
|
427
|
+
|
|
428
|
+
```javascript
|
|
429
|
+
// Wait for GDPR consent before proceeding
|
|
430
|
+
await agent.waitForConsent();
|
|
431
|
+
|
|
432
|
+
// Discover all actions + page meta
|
|
433
|
+
const disc = await agent.discover();
|
|
434
|
+
console.log(disc.actions, disc.meta);
|
|
435
|
+
|
|
436
|
+
// Run a sequence of actions (stops on first failure by default)
|
|
437
|
+
const results = await agent.runPipeline([
|
|
438
|
+
{ name: 'login', params: { email: 'a@b.com', pass: 'secret' } },
|
|
439
|
+
{ name: 'addToCart', params: { sku: 'ABC123' } },
|
|
440
|
+
{ name: 'checkout' }
|
|
441
|
+
]);
|
|
442
|
+
|
|
443
|
+
// Run actions in parallel
|
|
444
|
+
const parallel = await agent.executeParallel([
|
|
445
|
+
{ name: 'getCartCount' },
|
|
446
|
+
{ name: 'getWishlistCount' }
|
|
447
|
+
]);
|
|
448
|
+
|
|
449
|
+
// Capture screenshot (base64) for vision agents
|
|
450
|
+
const b64 = await agent.screenshot({ fullPage: true });
|
|
451
|
+
```
|
|
452
|
+
|
|
453
|
+
---
|
|
454
|
+
|
|
455
|
+
## Framework Packages
|
|
456
|
+
|
|
457
|
+
### Vue 3
|
|
458
|
+
|
|
459
|
+
```bash
|
|
460
|
+
npm install @web-agent-bridge/vue
|
|
461
|
+
```
|
|
462
|
+
|
|
463
|
+
```javascript
|
|
464
|
+
import { useWAB, useWABAction } from '@web-agent-bridge/vue';
|
|
465
|
+
|
|
466
|
+
// In setup()
|
|
467
|
+
const { ready, execute } = useWAB({ siteUrl: 'https://example.com' });
|
|
468
|
+
const cart = useWABAction('addToCart');
|
|
469
|
+
|
|
470
|
+
// In template handler
|
|
471
|
+
await cart.run({ sku: 'ABC123' });
|
|
472
|
+
console.log(cart.result.value);
|
|
473
|
+
```
|
|
474
|
+
|
|
475
|
+
### Svelte
|
|
476
|
+
|
|
477
|
+
```bash
|
|
478
|
+
npm install @web-agent-bridge/svelte
|
|
479
|
+
```
|
|
480
|
+
|
|
481
|
+
```svelte
|
|
482
|
+
<script>
|
|
483
|
+
import { createWAB, createWABAction } from '@web-agent-bridge/svelte';
|
|
484
|
+
|
|
485
|
+
const wab = createWAB();
|
|
486
|
+
const cart = createWABAction('addToCart');
|
|
487
|
+
|
|
488
|
+
async function add() {
|
|
489
|
+
await cart.run({ sku: 'ABC123' });
|
|
490
|
+
}
|
|
491
|
+
</script>
|
|
492
|
+
|
|
493
|
+
{#if $cart.loading}Adding...{/if}
|
|
494
|
+
{#if $cart.result}Added!{/if}
|
|
495
|
+
<button on:click={add}>Add to Cart</button>
|
|
496
|
+
```
|
|
497
|
+
|
|
498
|
+
### LangChain / LangGraph
|
|
499
|
+
|
|
500
|
+
```bash
|
|
501
|
+
npm install @web-agent-bridge/langchain
|
|
502
|
+
```
|
|
503
|
+
|
|
504
|
+
```javascript
|
|
505
|
+
const { WABToolkit } = require('@web-agent-bridge/langchain');
|
|
506
|
+
const { ChatOpenAI } = require('@langchain/openai');
|
|
507
|
+
const { AgentExecutor, createOpenAIToolsAgent } = require('langchain/agents');
|
|
508
|
+
|
|
509
|
+
// HTTP mode — discover + execute via the WAB server
|
|
510
|
+
const toolkit = new WABToolkit({ siteUrl: 'https://shop.example.com' });
|
|
511
|
+
const tools = await toolkit.getTools();
|
|
512
|
+
|
|
513
|
+
// Browser mode — use with Puppeteer/Playwright
|
|
514
|
+
const { WABAgent } = require('web-agent-bridge/sdk');
|
|
515
|
+
const toolkit2 = new WABToolkit({ agent: new WABAgent(page) });
|
|
516
|
+
const tools2 = await toolkit2.getTools();
|
|
517
|
+
|
|
518
|
+
// Pass tools to any LangChain agent
|
|
519
|
+
const llm = new ChatOpenAI({ model: 'gpt-4o' });
|
|
520
|
+
const agent = await createOpenAIToolsAgent({ llm, tools, prompt });
|
|
521
|
+
const executor = new AgentExecutor({ agent, tools });
|
|
522
|
+
await executor.invoke({ input: 'Add the first product to my cart' });
|
|
523
|
+
```
|
|
524
|
+
|
|
525
|
+
---
|
|
526
|
+
|
|
527
|
+
## GDPR / CCPA Consent
|
|
528
|
+
|
|
529
|
+
Load the consent script after `wab.min.js` to gate agent actions behind user consent:
|
|
530
|
+
|
|
531
|
+
```html
|
|
532
|
+
<script src="/script/wab.min.js"></script>
|
|
533
|
+
<script src="/script/wab-consent.js"></script>
|
|
534
|
+
<script>
|
|
535
|
+
WABConsent.showBanner({
|
|
536
|
+
policyUrl: '/privacy',
|
|
537
|
+
message: 'Allow AI agents to interact with this page?',
|
|
538
|
+
onAccept: () => WAB.init({ siteUrl: location.origin }),
|
|
539
|
+
onDecline: () => console.log('Agent access declined')
|
|
540
|
+
});
|
|
541
|
+
</script>
|
|
542
|
+
```
|
|
543
|
+
|
|
544
|
+
SDK agents can check consent programmatically:
|
|
545
|
+
|
|
546
|
+
```javascript
|
|
547
|
+
const agent = new WABAgent(page);
|
|
548
|
+
const ok = await agent.hasConsent(); // true | false
|
|
549
|
+
await agent.waitForConsent(); // blocks until Allow is clicked
|
|
550
|
+
```
|
|
551
|
+
|
|
552
|
+
---
|
|
553
|
+
|
|
554
|
+
## Agent Examples
|
|
555
|
+
|
|
556
|
+
Ready-to-run agent examples in the [`examples/`](examples/) directory:
|
|
557
|
+
|
|
558
|
+
| File | Description |
|
|
559
|
+
|---|---|
|
|
560
|
+
| `puppeteer-agent.js` | Basic agent using Puppeteer + `window.AICommands` |
|
|
561
|
+
| `bidi-agent.js` | Agent using WebDriver BiDi protocol via `window.__wab_bidi` |
|
|
562
|
+
| `vision-agent.js` | Vision/NLP agent — resolves natural language intents to actions using a local keyword-based resolver (no external API) |
|
|
563
|
+
|
|
564
|
+
## Framework + CMS Examples
|
|
565
|
+
|
|
566
|
+
Additional integration examples are available in:
|
|
567
|
+
|
|
568
|
+
| Path | Description |
|
|
569
|
+
|---|---|
|
|
570
|
+
| `examples/next-app-router/` | Next.js App Router integration with `@web-agent-bridge/react` |
|
|
571
|
+
| `examples/shopify-hydrogen/` | Hydrogen storefront integration with practical cart actions |
|
|
572
|
+
| `examples/wordpress-elementor/` | WordPress + Elementor setup with schema-assisted actions |
|
|
573
|
+
| `examples/saas-dashboard/` | Notion-style SaaS dashboard actions for KPI read + workflow triggers |
|
|
574
|
+
|
|
575
|
+
```bash
|
|
576
|
+
node examples/puppeteer-agent.js http://localhost:3000
|
|
577
|
+
node examples/bidi-agent.js http://localhost:3000
|
|
578
|
+
node examples/vision-agent.js http://localhost:3000
|
|
579
|
+
```
|
|
580
|
+
|
|
581
|
+
---
|
|
582
|
+
|
|
583
|
+
## Multi-Database Support
|
|
584
|
+
|
|
585
|
+
WAB defaults to SQLite but supports PostgreSQL and MySQL via database adapters.
|
|
586
|
+
|
|
587
|
+
```bash
|
|
588
|
+
# SQLite (default — no setup needed)
|
|
589
|
+
npm start
|
|
590
|
+
|
|
591
|
+
# PostgreSQL
|
|
592
|
+
npm install pg
|
|
593
|
+
DB_ADAPTER=postgresql DATABASE_URL=postgres://user:pass@localhost:5432/wab npm start
|
|
594
|
+
|
|
595
|
+
# MySQL
|
|
596
|
+
npm install mysql2
|
|
597
|
+
DB_ADAPTER=mysql DATABASE_URL=mysql://user:pass@localhost:3306/wab npm start
|
|
598
|
+
```
|
|
599
|
+
|
|
600
|
+
### When to Choose Which Database
|
|
601
|
+
|
|
602
|
+
| Scenario | Recommended DB | Why |
|
|
603
|
+
|---|---|---|
|
|
604
|
+
| Local dev / prototyping | SQLite | Zero setup, single file, instant |
|
|
605
|
+
| Small production (< 100 sites) | SQLite | Fast, no external dependencies |
|
|
606
|
+
| Medium production (100-10K sites) | PostgreSQL | Better concurrency, JSONB support |
|
|
607
|
+
| Large / enterprise production | PostgreSQL | Replication, backups, scalability |
|
|
608
|
+
| Existing MySQL infrastructure | MySQL | Integrate with what you already use |
|
|
609
|
+
|
|
610
|
+
See [`server/models/adapters/`](server/models/adapters/) for adapter implementations.
|
|
611
|
+
|
|
612
|
+
---
|
|
613
|
+
|
|
614
|
+
## Security Architecture
|
|
615
|
+
|
|
616
|
+
WAB implements defense-in-depth to protect the bridge from misuse:
|
|
617
|
+
|
|
618
|
+
### Secure License Exchange
|
|
619
|
+
|
|
620
|
+
1. **Dashboard snippet (recommended):** `siteId` + `configEndpoint`. The browser sends `POST /api/license/token` with `{ siteId }`; the server checks **Origin** against the site’s registered domain and issues a session token.
|
|
621
|
+
2. **Legacy:** `licenseKey` + `configEndpoint` (or deprecated `_licenseKey`) still works for token exchange but should not be embedded in public HTML.
|
|
622
|
+
3. **Session** is domain-locked (1h TTL); **analytics** use `sessionToken` on `POST /api/license/track` (not the license key).
|
|
623
|
+
4. **WebSocket** `/ws/analytics`: user JWT must **own** the `siteId`; admin JWT may observe any site.
|
|
624
|
+
|
|
625
|
+
```
|
|
626
|
+
Client Server
|
|
627
|
+
│── POST /api/license/token ──→│ { siteId } + Origin header
|
|
628
|
+
│ │ domain match → sessionToken
|
|
629
|
+
│←── { sessionToken, tier } ──│
|
|
630
|
+
│── POST /api/license/track ─→│ { sessionToken, actionName } + Origin
|
|
631
|
+
```
|
|
632
|
+
|
|
633
|
+
**Production:** set `JWT_SECRET`, `JWT_SECRET_ADMIN`, `STRIPE_WEBHOOK_SECRET`, `ALLOWED_ORIGINS`, and create the first admin via `BOOTSTRAP_ADMIN_*` or `node scripts/create-admin.js`.
|
|
634
|
+
|
|
635
|
+
### Security Sandbox
|
|
636
|
+
|
|
637
|
+
Every bridge instance runs inside a `SecuritySandbox` that provides:
|
|
638
|
+
|
|
639
|
+
- **Session tokens** — Unique cryptographic token per session prevents replay attacks
|
|
640
|
+
- **Origin validation** — Only whitelisted origins can interact with the bridge
|
|
641
|
+
- **Command validation** — All commands are validated for format, length, and blocklist
|
|
642
|
+
- **Audit logging** — Every action is logged with timestamp, agent fingerprint, and status
|
|
643
|
+
- **Escalation protection** — Attempts to access higher-tier features trigger automatic lockdown after 5 violations
|
|
644
|
+
- **Auto-lockdown** — Bridge becomes read-only when security violations are detected
|
|
645
|
+
|
|
646
|
+
```javascript
|
|
647
|
+
// Get security status
|
|
648
|
+
const info = bridge.getPageInfo();
|
|
649
|
+
console.log(info.security);
|
|
650
|
+
// { sandboxActive: true, locked: false, sessionToken: "a3f2..." }
|
|
651
|
+
|
|
652
|
+
// View audit log
|
|
653
|
+
const audit = bridge.security.getAuditLog(20);
|
|
654
|
+
```
|
|
655
|
+
|
|
656
|
+
### Selector Restrictions
|
|
657
|
+
|
|
658
|
+
Block sensitive page sections from agent access:
|
|
659
|
+
|
|
660
|
+
```javascript
|
|
661
|
+
window.AIBridgeConfig = {
|
|
662
|
+
restrictions: {
|
|
663
|
+
blockedSelectors: [".private", "[data-private]", "#payment-form"],
|
|
664
|
+
allowedSelectors: [".public-content"]
|
|
665
|
+
}
|
|
666
|
+
};
|
|
667
|
+
```
|
|
668
|
+
|
|
669
|
+
---
|
|
670
|
+
|
|
671
|
+
## Self-Healing Selectors
|
|
672
|
+
|
|
673
|
+
Modern SPAs frequently change their DOM structure. WAB's self-healing system ensures selectors keep working even when the page changes:
|
|
674
|
+
|
|
675
|
+
### How It Works
|
|
676
|
+
|
|
677
|
+
1. **Fingerprinting** — When actions are discovered, WAB stores a rich fingerprint of each element (tag, id, classes, text, ARIA attributes, position)
|
|
678
|
+
2. **7-Strategy Resolution** — When a selector breaks, WAB tries these strategies in order:
|
|
679
|
+
- `data-wab-id` attribute (most stable — add to your HTML)
|
|
680
|
+
- `data-testid` attribute
|
|
681
|
+
- Element ID
|
|
682
|
+
- `aria-label` (semantic, usually survives redesigns)
|
|
683
|
+
- `name` attribute
|
|
684
|
+
- Fuzzy text matching (bigram similarity > 70%)
|
|
685
|
+
- Role + position heuristic
|
|
686
|
+
3. **SPA Observer** — A `MutationObserver` watches for DOM changes and automatically re-discovers actions with a 500ms debounce
|
|
687
|
+
|
|
688
|
+
```javascript
|
|
689
|
+
// Check healing stats
|
|
690
|
+
const info = bridge.getPageInfo();
|
|
691
|
+
console.log(info.selfHealing);
|
|
692
|
+
// { tracked: 12, healed: 3, failed: 0 }
|
|
693
|
+
|
|
694
|
+
// Listen for healing events
|
|
695
|
+
bridge.events.on('selector:healed', (data) => {
|
|
696
|
+
console.log(`Healed: ${data.action} via ${data.strategy}`);
|
|
697
|
+
});
|
|
698
|
+
```
|
|
699
|
+
|
|
700
|
+
### Best Practices for Site Owners
|
|
701
|
+
|
|
702
|
+
Add `data-wab-id` attributes to critical elements for maximum stability:
|
|
703
|
+
|
|
704
|
+
```html
|
|
705
|
+
<button data-wab-id="signup-btn">Sign Up</button>
|
|
706
|
+
<form data-wab-id="login-form">...</form>
|
|
707
|
+
```
|
|
708
|
+
|
|
709
|
+
---
|
|
710
|
+
|
|
711
|
+
## Stealth Mode
|
|
712
|
+
|
|
713
|
+
For sites with anti-bot protection, WAB can simulate human-like interaction patterns. **Stealth mode requires explicit consent** to ensure ethical use.
|
|
714
|
+
|
|
715
|
+
```javascript
|
|
716
|
+
window.AIBridgeConfig = {
|
|
717
|
+
stealth: {
|
|
718
|
+
enabled: true,
|
|
719
|
+
consent: true // Required — confirms site owner authorizes human-like patterns
|
|
720
|
+
}
|
|
721
|
+
};
|
|
722
|
+
```
|
|
723
|
+
|
|
724
|
+
> **⚠️ Ethical Use Policy:** Stealth mode is designed for accessibility and testing on your own websites. Using it to bypass security controls on sites you do not own may violate terms of service and applicable laws.
|
|
725
|
+
|
|
726
|
+
When enabled, all interactions use:
|
|
727
|
+
|
|
728
|
+
| Feature | Description |
|
|
729
|
+
|---|---|
|
|
730
|
+
| **Mouse event chain** | `mouseover → mouseenter → mousemove → mousedown → mouseup → click` with natural coordinates |
|
|
731
|
+
| **Typing simulation** | Character-by-character input with 30-120ms delays per keystroke |
|
|
732
|
+
| **Scroll easing** | Multi-step scrolling with variable speed |
|
|
733
|
+
| **Random delays** | 50-400ms natural pauses between actions |
|
|
734
|
+
|
|
735
|
+
```javascript
|
|
736
|
+
// Enable/disable at runtime (consent required)
|
|
737
|
+
bridge.stealth.enable(true); // true = consent granted
|
|
738
|
+
bridge.stealth.disable();
|
|
739
|
+
```
|
|
740
|
+
|
|
741
|
+
---
|
|
742
|
+
|
|
743
|
+
## CLI
|
|
744
|
+
|
|
745
|
+
Install globally or use via npx:
|
|
746
|
+
|
|
747
|
+
```bash
|
|
748
|
+
# Run the server
|
|
749
|
+
npx web-agent-bridge start
|
|
750
|
+
npx web-agent-bridge start --port 8080
|
|
751
|
+
|
|
752
|
+
# Initialize a new project
|
|
753
|
+
npx web-agent-bridge init
|
|
754
|
+
```
|
|
755
|
+
|
|
756
|
+
---
|
|
757
|
+
|
|
758
|
+
## Environment Variables
|
|
759
|
+
|
|
760
|
+
See `.env.example`. Important:
|
|
761
|
+
|
|
762
|
+
```
|
|
763
|
+
PORT=3000
|
|
764
|
+
NODE_ENV=development
|
|
765
|
+
JWT_SECRET=long-random-user-signing-secret
|
|
766
|
+
JWT_SECRET_ADMIN=long-random-admin-signing-secret # required in production
|
|
767
|
+
ALLOWED_ORIGINS=http://localhost:3000,https://your-app.com
|
|
768
|
+
STRIPE_WEBHOOK_SECRET=whsec_... # Stripe webhook verify
|
|
769
|
+
CREDENTIALS_ENCRYPTION_KEY=... # optional SMTP password encryption
|
|
770
|
+
DB_ADAPTER=sqlite
|
|
771
|
+
DATABASE_URL=
|
|
772
|
+
```
|
|
773
|
+
|
|
774
|
+
First admin: set `BOOTSTRAP_ADMIN_EMAIL` / `BOOTSTRAP_ADMIN_PASSWORD` when the `admins` table is empty, or run `node scripts/create-admin.js <email> <password>`.
|
|
775
|
+
|
|
776
|
+
---
|
|
777
|
+
|
|
778
|
+
## License
|
|
779
|
+
|
|
780
|
+
MIT — Free to use, modify, and distribute.
|