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.
Files changed (94) hide show
  1. package/LICENSE +21 -21
  2. package/README.ar.md +446 -446
  3. package/README.md +780 -844
  4. package/bin/cli.js +80 -80
  5. package/bin/wab.js +80 -80
  6. package/examples/bidi-agent.js +119 -119
  7. package/examples/mcp-agent.js +94 -94
  8. package/examples/next-app-router/README.md +44 -0
  9. package/examples/puppeteer-agent.js +108 -108
  10. package/examples/saas-dashboard/README.md +55 -0
  11. package/examples/shopify-hydrogen/README.md +74 -0
  12. package/examples/vision-agent.js +171 -171
  13. package/examples/wordpress-elementor/README.md +77 -0
  14. package/package.json +69 -78
  15. package/public/.well-known/ai-assets.json +59 -0
  16. package/public/admin/login.html +84 -84
  17. package/public/ai.html +196 -0
  18. package/public/cookies.html +208 -208
  19. package/public/css/premium.css +317 -0
  20. package/public/css/styles.css +1235 -1235
  21. package/public/dashboard.html +704 -704
  22. package/public/demo.html +259 -0
  23. package/public/docs.html +585 -585
  24. package/public/feed.xml +89 -0
  25. package/public/index.html +495 -332
  26. package/public/js/auth-nav.js +31 -31
  27. package/public/js/auth-redirect.js +12 -12
  28. package/public/js/cookie-consent.js +56 -56
  29. package/public/js/wab-demo-page.js +721 -0
  30. package/public/js/ws-client.js +74 -74
  31. package/public/llms-full.txt +309 -0
  32. package/public/llms.txt +85 -0
  33. package/public/login.html +83 -83
  34. package/public/openapi.json +580 -0
  35. package/public/premium-dashboard.html +2487 -0
  36. package/public/premium.html +791 -0
  37. package/public/privacy.html +295 -295
  38. package/public/register.html +103 -103
  39. package/public/robots.txt +87 -0
  40. package/public/script/wab-consent.d.ts +36 -0
  41. package/public/script/wab-consent.js +104 -0
  42. package/public/script/wab-schema.js +131 -0
  43. package/public/script/wab.d.ts +108 -0
  44. package/public/script/wab.min.js +234 -0
  45. package/public/sitemap.xml +93 -0
  46. package/public/terms.html +254 -254
  47. package/public/video/tutorial.mp4 +0 -0
  48. package/script/ai-agent-bridge.js +1558 -1513
  49. package/sdk/README.md +55 -55
  50. package/sdk/index.d.ts +118 -0
  51. package/sdk/index.js +257 -203
  52. package/sdk/package.json +14 -14
  53. package/sdk/schema-discovery.js +83 -0
  54. package/server/config/secrets.js +94 -92
  55. package/server/index.js +0 -9
  56. package/server/middleware/adminAuth.js +30 -30
  57. package/server/middleware/auth.js +41 -41
  58. package/server/middleware/rateLimits.js +24 -24
  59. package/server/migrations/001_add_analytics_indexes.sql +7 -7
  60. package/server/migrations/002_premium_features.sql +418 -0
  61. package/server/models/adapters/index.js +33 -33
  62. package/server/models/adapters/mysql.js +183 -183
  63. package/server/models/adapters/postgresql.js +172 -172
  64. package/server/models/adapters/sqlite.js +7 -7
  65. package/server/models/db.js +561 -561
  66. package/server/routes/admin-premium.js +671 -0
  67. package/server/routes/admin.js +247 -247
  68. package/server/routes/api.js +131 -138
  69. package/server/routes/auth.js +51 -51
  70. package/server/routes/billing.js +45 -45
  71. package/server/routes/discovery.js +406 -329
  72. package/server/routes/license.js +240 -240
  73. package/server/routes/noscript.js +543 -543
  74. package/server/routes/premium-v2.js +686 -0
  75. package/server/routes/premium.js +724 -0
  76. package/server/routes/wab-api.js +476 -476
  77. package/server/services/agent-memory.js +625 -0
  78. package/server/services/email.js +204 -204
  79. package/server/services/fairness.js +420 -420
  80. package/server/services/plugins.js +747 -0
  81. package/server/services/premium.js +1883 -0
  82. package/server/services/self-healing.js +843 -0
  83. package/server/services/stripe.js +192 -192
  84. package/server/services/swarm.js +788 -0
  85. package/server/services/vision.js +871 -0
  86. package/server/utils/cache.js +125 -125
  87. package/server/utils/migrate.js +81 -81
  88. package/server/utils/secureFields.js +50 -50
  89. package/server/ws.js +101 -101
  90. package/docs/DEPLOY.md +0 -118
  91. package/docs/SPEC.md +0 -1540
  92. package/wab-mcp-adapter/README.md +0 -136
  93. package/wab-mcp-adapter/index.js +0 -555
  94. package/wab-mcp-adapter/package.json +0 -17
package/README.md CHANGED
@@ -1,844 +1,780 @@
1
- # Web Agent Bridge (WAB)
2
-
3
- [![npm](https://img.shields.io/npm/v/web-agent-bridge)](https://www.npmjs.com/package/web-agent-bridge)
4
- [![CI](https://github.com/abokenan444/web-agent-bridge/actions/workflows/ci.yml/badge.svg)](https://github.com/abokenan444/web-agent-bridge/actions/workflows/ci.yml)
5
- [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)
6
- [![Node.js](https://img.shields.io/badge/node-%3E%3D18-brightgreen.svg)](https://nodejs.org/)
7
- [![Docker](https://img.shields.io/badge/docker-ready-blue.svg)](https://hub.docker.com/)
8
- [![PRs Welcome](https://img.shields.io/badge/PRs-welcome-brightgreen.svg)](CONTRIBUTING.md)
9
- [![Socket](https://img.shields.io/badge/Socket-Verified-brightgreen.svg)](https://socket.dev/npm/package/web-agent-bridge)
10
-
11
- > **robots.txt told bots what NOT to do. WAB tells AI agents what they CAN do.**
12
-
13
- **English** | **[العربية](README.ar.md)** | **[Protocol Spec](docs/SPEC.md)** | **[Socket Report](https://socket.dev/npm/package/web-agent-bridge)**
14
-
15
- WAB is an **open protocol + runtime** for AI agents to interact with websites — the **OpenAPI for human-facing pages**. It provides a standardized discovery format (`agent-bridge.json`), a command protocol, and a fairness layer that ensures small businesses get equal visibility alongside large platforms.
16
-
17
- WAB transforms websites from opaque HTML into **agent-readable endpoints** with declared capabilities, permissions, and actions. AI agents discover what a site offers, authenticate, and execute commands through a uniform protocol — no DOM scraping, no guesswork, no bias toward big brands.
18
-
19
- ### Architecture: Protocol + Runtime + Ecosystem
20
-
21
- ```
22
- ┌──────────────────────────────────────────────────────────┐
23
- │ WAB Protocol (Spec)
24
- │ agent-bridge.json · Commands · Lifecycle · Fairness │
25
- ├────────────┬───────────────────┬─────────────────────────┤
26
- │ JS Runtime │ HTTP Transport │ MCP Adapter │
27
- AICommands │ REST + WebSocket │ WAB → MCP Tools │
28
- ├────────────┴───────────────────┴─────────────────────────┤
29
- Discovery Registry + Fairness Engine │
30
- └──────────────────────────────────────────────────────────┘
31
- ```
32
-
33
- ### Three Paths to WAB
34
-
35
- | Path | For | How |
36
- |---|---|---|
37
- | **🏢 Website Owner** | Control how AI interacts with your site | Embed the script, publish `agent-bridge.json` |
38
- | **🤖 Agent Developer** | Build reliable agents that work on any WAB-enabled site | Use `window.AICommands`, the Agent SDK, or the MCP Adapter |
39
- | **🔧 Self-Hosting** | Run the full WAB platform for your organization | Clone, deploy, manage licenses & analytics |
40
- | **🔌 MCP Integration** | Connect WAB to Claude, GPT, or any MCP-compatible agent | Use `wab-mcp-adapter` |
41
- | **WordPress** | Sites powered by WP | Use the **[Web Agent Bridge WordPress plugin](web-agent-bridge-wordpress/README.md)** |
42
-
43
- ---
44
-
45
- ## What's New in v1.1.0
46
-
47
- - **WAB Protocol Specification v1.0** — Formal protocol spec (`docs/SPEC.md`) with discovery format, command protocol, lifecycle, and fairness layer
48
- - **Discovery Protocol** — Sites publish `agent-bridge.json` or `/.well-known/wab.json` for agent discovery
49
- - **MCP Adapter** — `wab-mcp-adapter` converts WAB actions into MCP tools for Claude/GPT integration
50
- - **Fairness Engine** — Neutrality layer ensures equal visibility for small businesses and independent sites
51
- - **Discovery Registry** — Public searchable directory of WAB-enabled sites with fairness-weighted results
52
- - **9 Protocol Commands** — `wab.discover`, `wab.getContext`, `wab.getActions`, `wab.executeAction`, `wab.readContent`, `wab.getPageInfo`, `wab.authenticate`, `wab.subscribe`, `wab.ping`
53
-
54
- ---
55
-
56
- ## Features
57
-
58
- ### Protocol Layer
59
- - **WAB Specification v1.0** — Formal protocol spec defining discovery, commands, lifecycle, and fairness ([docs/SPEC.md](docs/SPEC.md))
60
- - **Discovery Protocol** — Sites declare capabilities via `agent-bridge.json` or `/.well-known/wab.json`
61
- - **Command Protocol** — 9 standard methods with request/response format (transport-agnostic)
62
- - **Lifecycle Protocol** — Discover → Authenticate → Plan → Execute → Confirm
63
- - **MCP Compatibility** — Full adapter for Model Context Protocol (Claude, GPT, LangChain)
64
-
65
- ### Fairness & Neutrality
66
- - **Fairness Engine** — Neutrality scoring ensures small businesses get equal agent visibility
67
- - **Discovery Registry** Public directory of WAB-enabled sites with anti-bias ranking
68
- - **Commission Transparency** — Sites declare commission rates; agents can favor direct providers
69
- - **Independent Business Priority** — Self-declared independent sites get fairness scoring boost
70
-
71
- ### Runtime
72
- - **Auto-Discovery** — Automatically detects buttons, forms, and navigation on the page
73
- - **Permission System** — Granular control over what AI agents can do (click, fill forms, API access, etc.)
74
- - **Standardized Interface** Unified `window.AICommands` object any agent can consume
75
- - **Self-Healing Selectors** — Resilient element resolution with 7-strategy fuzzy matching for SPAs
76
- - **Security Sandbox** — Origin validation, session tokens, command signing, audit logging, auto-lockdown
77
- - **Stealth Mode** — Human-like interaction patterns (requires explicit consent)
78
- - **NoJS Fallback** — CSS tracking, pixel tracking, and SSR bridge for JavaScript-disabled environments
79
-
80
- ### Infrastructure
81
- - **Secure License Exchange** — Embed uses `siteId` + token exchange; keys stay in the dashboard
82
- - **Rate Limiting** — Multi-dimensional abuse protection (IP + license key + site)
83
- - **Analytics Dashboard** Track how AI agents interact with your site
84
- - **Real-Time Analytics** — WebSocket-based live event streaming with auto-reconnection
85
- - **WebDriver BiDi Compatible** Standard protocol support via `window.__wab_bidi`
86
- - **CDN Versioning** — Serve scripts via versioned URLs (`/v1/ai-agent-bridge.js`, `/latest/ai-agent-bridge.js`)
87
- - **Docker Ready** — One-command deployment with Docker Compose
88
- - **Multi-Database** SQLite (default), PostgreSQL, MySQL via pluggable adapters
89
- - **Agent SDK** — Built-in SDK for building AI agents with Puppeteer/Playwright
90
- - **Admin Dashboard** — User management, tier grants, system analytics
91
- - **Stripe Integration** — Payment processing with customer portal
92
-
93
- ---
94
-
95
- ## Premium Services (webagentbridge.com)
96
-
97
- The open-source core is free forever. For teams and businesses that need more, **[webagentbridge.com](https://webagentbridge.com/premium)** offers paid add-ons and higher-tier plans:
98
-
99
- | # | Service | Plans |
100
- |---|---------|-------|
101
- | 1 | **Agent Traffic Intelligence** — Deep analytics: agent type, platform, country, behavioral classification, anomaly alerts | Starter+ |
102
- | 2 | **Advanced Exploit Shield** — Behavioral fingerprint blocking, unauthorized command detection, periodic security reports | Pro+ |
103
- | 3 | **Pre-built Smart Actions Library** — Ready-made action packs for WooCommerce, Shopify, WordPress, Salesforce with auto-updates | Starter+ |
104
- | 4 | **Custom AI Agents as a Service** Visual agent builder, task scheduling, cloud-based execution | Pro+ |
105
- | 5 | **CRM & Cloud Integrations** — Salesforce, HubSpot, Zoho; export to BigQuery/Snowflake/Datadog; custom webhooks | Pro+ |
106
- | 6 | **Multi-Tenant Permission Management** — Sub-users, per-user quotas, central control panel for agencies | Enterprise |
107
- | 7 | **AI-Powered Priority Support** — Smart chatbot, live video sessions, SLA from 15 min (Enterprise) to same-day (Starter) | Starter+ |
108
- | 8 | **Custom Bridge Script** — Plugin-based custom actions, performance optimization, automatic zero-day patches | Pro+ |
109
- | 9 | **Stealth Mode Pro** — Customizable human-like behavior profiles, anti-detection bypass, monthly fingerprint updates | Pro+ |
110
- | 10 | **Private CDN** — Global edge network, custom domain (`bridge.yoursite.com`), geo performance stats | Pro+ |
111
- | 11 | **Extended Audit Logs & Compliance** — 7-year retention, HIPAA/GDPR/SOC2 settings, signed PDF/CSV exports | Enterprise |
112
- | 12 | **Virtual Sandbox Environment** — Isolated test environment, simulated agent traffic, before/after benchmarks | Enterprise |
113
-
114
- Plans: **Free** (open source) → **Starter $9/mo** → **Pro $29/mo** → **Enterprise (custom)**. Visit [webagentbridge.com/premium](https://webagentbridge.com/premium) for details.
115
-
116
- ---
117
-
118
- ## Quick Start
119
-
120
- ### 1. Install & Run the Server
121
-
122
- ```bash
123
- # Option A: Clone and run
124
- git clone https://github.com/abokenan444/web-agent-bridge.git
125
- cd web-agent-bridge
126
- npm install
127
- cp .env.example .env
128
- npm start
129
-
130
- # Option B: npx (one command)
131
- npx web-agent-bridge start
132
-
133
- # Option C: Docker
134
- docker compose up -d
135
- ```
136
-
137
- ### 2. Create an Account
138
-
139
- Visit `http://localhost:3000/register` and create an account, then add your site from the dashboard.
140
-
141
- ### 3. Add the Script to Your Website
142
-
143
- ```html
144
- <!-- Recommended: copy the snippet from your dashboard (uses siteId only) -->
145
- <script>
146
- window.AIBridgeConfig = {
147
- siteId: "your-site-uuid-from-dashboard",
148
- configEndpoint: "https://yourserver.com/api/license/token",
149
- agentPermissions: {
150
- readContent: true,
151
- click: true,
152
- fillForms: true,
153
- scroll: true
154
- }
155
- };
156
- </script>
157
- <script src="https://yourserver.com/script/ai-agent-bridge.js"></script>
158
- ```
159
-
160
- 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.
161
-
162
- ### 4. AI Agents Can Now Interact
163
-
164
- ```javascript
165
- // From the AI agent's side
166
- const bridge = window.AICommands;
167
- const actions = bridge.getActions(); // discover actions
168
- await bridge.execute("signup"); // execute an action
169
- const info = bridge.getPageInfo(); // get page metadata
170
- ```
171
-
172
- ---
173
-
174
- ## Discovery Protocol (`agent-bridge.json`)
175
-
176
- Any website can declare its WAB capabilities by serving a discovery document at `/agent-bridge.json` or `/.well-known/wab.json`. AI agents fetch this file to understand what a site offers before interacting.
177
-
178
- ```json
179
- {
180
- "wab_version": "1.0",
181
- "provider": {
182
- "name": "Local Bookshop",
183
- "domain": "localbookshop.com",
184
- "category": "e-commerce",
185
- "description": "Independent bookshop"
186
- },
187
- "capabilities": {
188
- "commands": ["readContent", "click", "fillForms"],
189
- "permissions": { "readContent": true, "click": true, "fillForms": true },
190
- "tier": "starter",
191
- "transport": ["js_global", "http"]
192
- },
193
- "agent_access": {
194
- "bridge_script": "/script/ai-agent-bridge.js",
195
- "api_base": "/api/license",
196
- "selectors": { "search": "#search-input", "cart": ".add-to-cart" }
197
- },
198
- "fairness": {
199
- "is_independent": true,
200
- "commission_rate": 0,
201
- "direct_benefit": "Owner is the producer",
202
- "neutrality_score": 85
203
- },
204
- "security": {
205
- "session_required": true,
206
- "origin_validation": true,
207
- "rate_limit": 60,
208
- "sandbox": true
209
- }
210
- }
211
- ```
212
-
213
- WAB servers auto-generate this document from each site's configuration. No manual file creation needed — register your site and the discovery endpoint is live.
214
-
215
- ### Discovery API Endpoints
216
-
217
- | Endpoint | Method | Description |
218
- |---|---|---|
219
- | `/.well-known/wab.json` | GET | Discovery document (domain-matched) |
220
- | `/agent-bridge.json` | GET | Alternative discovery location |
221
- | `/api/discovery/:siteId` | GET | Discovery document for a specific site |
222
- | `/api/discovery/registry` | GET | Public directory of WAB-enabled sites |
223
- | `/api/discovery/search` | GET | Fairness-weighted site search |
224
- | `/api/discovery/register` | POST | Register site in directory (authenticated) |
225
-
226
- ---
227
-
228
- ## MCP Adapter (Model Context Protocol)
229
-
230
- The `wab-mcp-adapter` converts WAB capabilities into MCP tools, so Claude, GPT, LangChain, or any MCP-compatible agent can interact with WAB-enabled sites.
231
-
232
- ```javascript
233
- const { WABMCPAdapter } = require('web-agent-bridge/wab-mcp-adapter');
234
-
235
- const adapter = new WABMCPAdapter({
236
- siteUrl: 'https://example.com',
237
- transport: 'http'
238
- });
239
-
240
- // Discover site capabilities
241
- const discovery = await adapter.discover();
242
-
243
- // Get all available MCP tools
244
- const tools = await adapter.getTools();
245
- // → [{ name: 'wab_discover', ... }, { name: 'wab_click_signup', ... }, ...]
246
-
247
- // Execute a tool (just like any MCP tool call)
248
- const result = await adapter.executeTool('wab_execute_action', {
249
- name: 'signup',
250
- data: { email: 'user@test.com' }
251
- });
252
- ```
253
-
254
- ### Built-in MCP Tools
255
-
256
- | Tool | Description |
257
- |---|---|
258
- | `wab_discover` | Discover site capabilities and fairness data |
259
- | `wab_get_actions` | List all available actions |
260
- | `wab_execute_action` | Execute any action by name |
261
- | `wab_read_content` | Read page content by CSS selector |
262
- | `wab_get_page_info` | Get page metadata and bridge status |
263
- | `wab_fairness_search` | Search WAB registry with fairness-weighted results |
264
- | `wab_authenticate` | Authenticate with a WAB site |
265
-
266
- See [`wab-mcp-adapter/README.md`](wab-mcp-adapter/README.md) for the full API reference.
267
-
268
- ---
269
-
270
- ## Fairness Engine
271
-
272
- WAB includes a **Neutrality Layer** a fairness engine that prevents AI agents from systematically favoring large platforms over small businesses.
273
-
274
- ### How It Works
275
-
276
- 1. **Neutrality Scoring** Each site gets a score (0-100) based on config quality, trust signatures, and commission transparency — not brand recognition
277
- 2. **Anti-Bias Ranking** Search results are fairness-weighted: independent businesses get +15%, transparent commission sites get +10%
278
- 3. **Position Rotation** Top results are shuffled to prevent position lock-in
279
- 4. **Monopoly Prevention** — No single provider can dominate more than 30% of top results
280
-
281
- ### Register Your Site
282
-
283
- ```bash
284
- # Register in the WAB discovery directory
285
- curl -X POST https://yourserver.com/api/discovery/register \
286
- -H "Authorization: Bearer YOUR_JWT" \
287
- -H "Content-Type: application/json" \
288
- -d '{
289
- "siteId": "your-site-uuid",
290
- "category": "e-commerce",
291
- "is_independent": true,
292
- "commission_rate": 0,
293
- "direct_benefit": "Products from local artisans",
294
- "tags": ["handmade", "local", "organic"]
295
- }'
296
- ```
297
-
298
- ---
299
-
300
- ## Project Structure
301
-
302
- ```
303
- web-agent-bridge/
304
- ├── docs/
305
- │ └── SPEC.md # WAB Protocol Specification v1.0
306
- ├── server/ # Express.js backend
307
- │ ├── index.js # Server entry point
308
- │ ├── routes/
309
- │ │ ├── auth.js # Authentication (register/login)
310
- │ │ ├── api.js # Sites, config, analytics API
311
- │ │ ├── license.js # License verification & token exchange
312
- │ │ ├── discovery.js # Discovery protocol endpoints
313
- │ │ ├── noscript.js # NoJS fallback (pixel, CSS, SSR)
314
- │ │ ├── admin.js # Admin dashboard API
315
- │ │ └── billing.js # Stripe billing integration
316
- │ ├── services/
317
- │ │ └── fairness.js # Fairness engine & neutrality layer
318
- │ ├── middleware/
319
- │ │ └── auth.js # JWT authentication middleware
320
- │ ├── models/
321
- │ │ └── db.js # SQLite database & operations
322
- │ ├── migrations/ # Numbered SQL migrations
323
- │ └── utils/
324
- │ ├── cache.js # In-memory cache + analytics queue
325
- │ └── migrate.js # Migration runner
326
- ├── wab-mcp-adapter/ # MCP adapter for WAB → Claude/GPT
327
- │ ├── index.js # WABMCPAdapter class
328
- │ ├── package.json
329
- │ └── README.md
330
- ├── public/ # Frontend
331
- │ ├── index.html # Landing page
332
- │ ├── dashboard.html # Management dashboard
333
- │ ├── docs.html # Documentation
334
- │ ├── admin/ # Admin panel
335
- │ ├── js/ # Client-side utilities
336
- │ └── css/styles.css # Design system
337
- ├── script/
338
- │ └── ai-agent-bridge.js # The bridge script (embed in websites)
339
- ├── examples/ # Agent examples (Puppeteer, BiDi, MCP, Vision)
340
- ├── sdk/ # Agent SDK for Puppeteer/Playwright
341
- ├── .env # Environment variables
342
- └── package.json
343
- ```
344
-
345
- ---
346
-
347
- ## API Endpoints
348
-
349
- ### Authentication
350
- | Endpoint | Method | Description |
351
- |---|---|---|
352
- | `/api/auth/register` | POST | Create account |
353
- | `/api/auth/login` | POST | Sign in, receive JWT |
354
- | `/api/auth/me` | GET | Get current user |
355
-
356
- ### Sites
357
- | Endpoint | Method | Description |
358
- |---|---|---|
359
- | `/api/sites` | GET | List your sites |
360
- | `/api/sites` | POST | Add a new site |
361
- | `/api/sites/:id` | GET | Get site details |
362
- | `/api/sites/:id/config` | PUT | Update configuration |
363
- | `/api/sites/:id/tier` | PUT | Change subscription tier |
364
- | `/api/sites/:id` | DELETE | Delete a site |
365
- | `/api/sites/:id/snippet` | GET | Get install code snippet |
366
- | `/api/sites/:id/analytics` | GET | Get analytics data |
367
-
368
- ### License (Public)
369
- | Endpoint | Method | Description |
370
- |---|---|---|
371
- | `/api/license/verify` | POST | Verify license key for domain (cached) |
372
- | `/api/license/token` | POST | Exchange `siteId` (Origin must match domain) or `licenseKey` for session token |
373
- | `/api/license/session` | POST | Validate session token (domain-locked) |
374
- | `/api/license/track` | POST | Record analytics (`sessionToken` + Origin; legacy `licenseKey` only if `ALLOW_LEGACY_LICENSE_TRACK`) |
375
-
376
- ### Discovery Protocol (Public)
377
- | Endpoint | Method | Description |
378
- |---|---|---|
379
- | `/.well-known/wab.json` | GET | Discovery document for the requesting domain |
380
- | `/agent-bridge.json` | GET | Alternative discovery location |
381
- | `/api/discovery/:siteId` | GET | Discovery document for a specific site |
382
- | `/api/discovery/registry` | GET | Public directory of WAB-enabled sites |
383
- | `/api/discovery/search?q=&category=` | GET | Fairness-weighted site search |
384
- | `/api/discovery/register` | POST | Register site in directory (authenticated) |
385
-
386
- ---
387
-
388
- ## Bridge Script API
389
-
390
- Once loaded, `window.AICommands` exposes:
391
-
392
- | Method | Description |
393
- |---|---|
394
- | `discover()` | Get full discovery document with protocol info and fairness data |
395
- | `ping()` | Health check — returns version, protocol, ready state |
396
- | `getActions(category?)` | List available actions |
397
- | `getAction(name)` | Get a specific action |
398
- | `execute(name, params?)` | Execute an action |
399
- | `readContent(selector)` | Read element content |
400
- | `getPageInfo()` | Get page and bridge metadata |
401
- | `subscribe(event, callback)` | Subscribe to events with subscription ID |
402
- | `unsubscribe(subscriptionId)` | Unsubscribe from events |
403
- | `waitForElement(selector, timeout?)` | Wait for DOM element |
404
- | `waitForNavigation(timeout?)` | Wait for URL change |
405
- | `registerAction(def)` | Register a custom action |
406
- | `authenticate(key, meta?)` | Authenticate an agent |
407
- | `refresh()` | Re-scan the page |
408
- | `onReady(callback)` | Callback when bridge is ready |
409
- | `events.on(event, cb)` | Subscribe to raw events |
410
-
411
- ---
412
-
413
- ## Configuration
414
-
415
- ```javascript
416
- window.AIBridgeConfig = {
417
- // Recommended — copy siteId from dashboard snippet (no license key in HTML)
418
- siteId: "uuid-from-dashboard",
419
- configEndpoint: "/api/license/token",
420
-
421
- // Legacy: token exchange via license key (avoid embedding in public pages)
422
- // licenseKey: "WAB-...",
423
-
424
- agentPermissions: {
425
- readContent: true, // Read page text
426
- click: true, // Click elements
427
- fillForms: false, // Fill/submit forms
428
- scroll: true, // Scroll page
429
- navigate: false, // Navigate pages
430
- apiAccess: false, // Internal API calls (Pro+)
431
- automatedLogin: false, // Auto login (Starter+)
432
- extractData: false // Data extraction (Pro+)
433
- },
434
- restrictions: {
435
- allowedSelectors: [],
436
- blockedSelectors: [".private", "[data-private]"],
437
- requireLoginForActions: ["apiAccess"],
438
- rateLimit: { maxCallsPerMinute: 60 }
439
- },
440
- logging: { enabled: false, level: "basic" }
441
- };
442
- ```
443
-
444
- ---
445
-
446
- ## Subscription Tiers
447
-
448
- | Feature | Free | Starter | Pro | Enterprise |
449
- |---|:---:|:---:|:---:|:---:|
450
- | Auto-discovery | | | ✓ | ✓ |
451
- | Click/Scroll | ✓ | ✓ | ✓ | ✓ |
452
- | Form filling | ✓ | ✓ | ✓ | ✓ |
453
- | Basic logging | ✓ | ✓ | ✓ | ✓ |
454
- | Automated login | ✗ | ✓ | ✓ | ✓ |
455
- | Analytics dashboard | ✗ | ✓ | ✓ | ✓ |
456
- | API access | ✗ | ✗ | ✓ | ✓ |
457
- | Data extraction | ✗ | ✗ | ✓ | ✓ |
458
- | Custom rate limits | ✗ | ✗ | ✗ | ✓ |
459
- | Webhooks | ✗ | ✗ | ✗ | ✓ |
460
-
461
- ---
462
-
463
- ## Tech Stack
464
-
465
- - **Protocol**: WAB Specification v1.0 with RFC 2119 conformance levels
466
- - **Backend**: Node.js + Express + WebSocket (ws)
467
- - **Database**: SQLite (via better-sqlite3) with migration runner
468
- - **Auth**: JWT + bcrypt + session tokens (domain-locked)
469
- - **MCP**: WAB-to-MCP adapter for Claude, GPT, LangChain integration
470
- - **Fairness**: Neutrality engine with anti-bias ranking and monopoly prevention
471
- - **Discovery**: Auto-generated `agent-bridge.json` + public registry
472
- - **Caching**: In-memory TTL cache + batched analytics queue
473
- - **Payments**: Stripe integration with billing portal
474
- - **Frontend**: Vanilla HTML/CSS/JS (no framework dependencies)
475
- - **Security**: Helmet, CORS, CSP, multi-layer rate limiting, sandbox
476
- - **Containers**: Docker + Docker Compose
477
- - **CI/CD**: GitHub Actions (test + auto-publish to npm)
478
- - **Testing**: Jest + Supertest
479
-
480
- ---
481
-
482
- ## WebDriver BiDi Compatibility
483
-
484
- WAB exposes a `window.__wab_bidi` interface for agents using standardized WebDriver BiDi protocol:
485
-
486
- ```javascript
487
- // Get BiDi context
488
- const context = window.__wab_bidi.getContext();
489
-
490
- // Send BiDi command
491
- const result = await window.__wab_bidi.send({
492
- id: 1,
493
- method: 'wab.executeAction',
494
- params: { name: 'signup', data: {} }
495
- });
496
-
497
- // Supported methods:
498
- // wab.discover, wab.getContext, wab.getActions, wab.executeAction,
499
- // wab.readContent, wab.getPageInfo, wab.authenticate, wab.subscribe, wab.ping
500
- ```
501
-
502
- ---
503
-
504
- ## Real-Time Analytics (WebSocket)
505
-
506
- Connect to `ws://localhost:3000/ws/analytics` for live analytics. Use the built-in `WABWebSocket` client for automatic reconnection with exponential backoff:
507
-
508
- ```javascript
509
- // Recommended: use the auto-reconnecting client
510
- import { WABWebSocket } from './js/ws-client.js';
511
-
512
- const ws = new WABWebSocket('jwt-token', 'site-id');
513
- ws.on('analytic', (data) => console.log(data));
514
- ws.on('reconnecting', ({ attempt, delay }) => console.log(`Reconnecting #${attempt}...`));
515
- ws.connect();
516
- ```
517
-
518
- ```javascript
519
- // Or connect manually
520
- const ws = new WebSocket('ws://localhost:3000/ws/analytics');
521
- ws.onopen = () => ws.send(JSON.stringify({ type: 'auth', token: 'jwt-token', siteId: 'site-id' }));
522
- ws.onmessage = (e) => console.log(JSON.parse(e.data));
523
- ```
524
-
525
- ### WebSocket Message Protocol
526
-
527
- **Client Server Messages:**
528
-
529
- | Message | Fields | Description |
530
- |---|---|---|
531
- | `auth` | `type`, `token`, `siteId` | Authenticate and subscribe to a site's events |
532
-
533
- ```json
534
- { "type": "auth", "token": "eyJhbGciOi...", "siteId": "uuid-of-site" }
535
- ```
536
-
537
- **Server Client Messages:**
538
-
539
- | Message Type | Fields | Description |
540
- |---|---|---|
541
- | `auth:success` | `type`, `siteId` | Authentication succeeded |
542
- | `analytic` | `type`, `timestamp`, `actionName`, `agentId`, `success` | Real-time analytics event |
543
- | `error` | `type`, `message` | Error (invalid auth, malformed message) |
544
-
545
- ```json
546
- // Success response
547
- { "type": "auth:success", "siteId": "uuid-of-site" }
548
-
549
- // Analytics event
550
- {
551
- "type": "analytic",
552
- "timestamp": "2024-01-15T10:30:00.000Z",
553
- "actionName": "click-signup",
554
- "agentId": "agent-123",
555
- "triggerType": "click",
556
- "success": true
557
- }
558
-
559
- // Error
560
- { "type": "error", "message": "Invalid message or auth failed" }
561
- ```
562
-
563
- **Connection Lifecycle:**
564
- 1. Connect to `ws://host:port/ws/analytics`
565
- 2. Send `auth` message with valid JWT and site ID
566
- 3. Receive `auth:success` confirmation
567
- 4. Receive `analytic` events as they occur
568
- 5. Server sends heartbeat pings every 30 seconds — dead connections are cleaned up automatically
569
-
570
- ---
571
-
572
- ## CDN & Versioning
573
-
574
- Scripts are served at versioned URLs for cache-safe deployments:
575
-
576
- | URL | Description |
577
- |---|---|
578
- | `/script/ai-agent-bridge.js` | Default path |
579
- | `/v1/ai-agent-bridge.js` | Version-pinned (recommended) |
580
- | `/latest/ai-agent-bridge.js` | Always latest (use with caution) |
581
-
582
- ---
583
-
584
- ## Docker
585
-
586
- ```bash
587
- # Quick start
588
- docker compose up -d
589
-
590
- # Or build manually
591
- docker build -t web-agent-bridge .
592
- docker run -p 3000:3000 -e JWT_SECRET=your-secret -e JWT_SECRET_ADMIN=your-admin-secret web-agent-bridge
593
- ```
594
-
595
- ---
596
-
597
- ## Testing
598
-
599
- ```bash
600
- npm test
601
- ```
602
-
603
- Tests cover: authentication, site CRUD, config management, license verification, analytics tracking, and static pages.
604
-
605
- ---
606
-
607
- ## Agent SDK
608
-
609
- WAB includes a built-in SDK for building AI agents. See [`sdk/README.md`](sdk/README.md) for full documentation.
610
-
611
- ```javascript
612
- const puppeteer = require('puppeteer');
613
- const { WABAgent } = require('web-agent-bridge/sdk');
614
-
615
- const browser = await puppeteer.launch();
616
- const page = await browser.newPage();
617
- const agent = new WABAgent(page);
618
-
619
- await agent.navigateAndWait('https://example.com');
620
- const actions = await agent.getActions();
621
- await agent.execute('signup', { email: 'user@test.com' });
622
- await browser.close();
623
- ```
624
-
625
- ---
626
-
627
- ## Agent Examples
628
-
629
- Ready-to-run agent examples in the [`examples/`](examples/) directory:
630
-
631
- | File | Description |
632
- |---|---|
633
- | `puppeteer-agent.js` | Basic agent using Puppeteer + `window.AICommands` |
634
- | `bidi-agent.js` | Agent using WebDriver BiDi protocol via `window.__wab_bidi` |
635
- | `mcp-agent.js` | MCP adapter demo — WAB actions as MCP tools for Claude/GPT |
636
- | `vision-agent.js` | Vision/NLP agent — resolves natural language intents to actions using a local keyword-based resolver (no external API) |
637
-
638
- ```bash
639
- node examples/puppeteer-agent.js http://localhost:3000
640
- node examples/bidi-agent.js http://localhost:3000
641
- node examples/mcp-agent.js http://localhost:3000
642
- node examples/vision-agent.js http://localhost:3000
643
- ```
644
-
645
- ---
646
-
647
- ## Multi-Database Support
648
-
649
- WAB defaults to SQLite but supports PostgreSQL and MySQL via database adapters.
650
-
651
- ```bash
652
- # SQLite (default — no setup needed)
653
- npm start
654
-
655
- # PostgreSQL
656
- npm install pg
657
- DB_ADAPTER=postgresql DATABASE_URL=postgres://user:pass@localhost:5432/wab npm start
658
-
659
- # MySQL
660
- npm install mysql2
661
- DB_ADAPTER=mysql DATABASE_URL=mysql://user:pass@localhost:3306/wab npm start
662
- ```
663
-
664
- ### When to Choose Which Database
665
-
666
- | Scenario | Recommended DB | Why |
667
- |---|---|---|
668
- | Local dev / prototyping | SQLite | Zero setup, single file, instant |
669
- | Small production (< 100 sites) | SQLite | Fast, no external dependencies |
670
- | Medium production (100-10K sites) | PostgreSQL | Better concurrency, JSONB support |
671
- | Large / enterprise production | PostgreSQL | Replication, backups, scalability |
672
- | Existing MySQL infrastructure | MySQL | Integrate with what you already use |
673
-
674
- See [`server/models/adapters/`](server/models/adapters/) for adapter implementations.
675
-
676
- ---
677
-
678
- ## Security Architecture
679
-
680
- WAB implements defense-in-depth to protect the bridge from misuse:
681
-
682
- ### Secure License Exchange
683
-
684
- 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.
685
- 2. **Legacy:** `licenseKey` + `configEndpoint` (or deprecated `_licenseKey`) still works for token exchange but should not be embedded in public HTML.
686
- 3. **Session** is domain-locked (1h TTL); **analytics** use `sessionToken` on `POST /api/license/track` (not the license key).
687
- 4. **WebSocket** `/ws/analytics`: user JWT must **own** the `siteId`; admin JWT may observe any site.
688
-
689
- ```
690
- Client Server
691
- │── POST /api/license/token ──→│ { siteId } + Origin header
692
- │ │ domain match sessionToken
693
- │←── { sessionToken, tier } ──│
694
- │── POST /api/license/track ─→│ { sessionToken, actionName } + Origin
695
- ```
696
-
697
- **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`.
698
-
699
- ### Security Sandbox
700
-
701
- Every bridge instance runs inside a `SecuritySandbox` that provides:
702
-
703
- - **Session tokens** — Unique cryptographic token per session prevents replay attacks
704
- - **Origin validation** — Only whitelisted origins can interact with the bridge
705
- - **Command validation** — All commands are validated for format, length, and blocklist
706
- - **Audit logging** — Every action is logged with timestamp, agent fingerprint, and status
707
- - **Escalation protection** — Attempts to access higher-tier features trigger automatic lockdown after 5 violations
708
- - **Auto-lockdown** — Bridge becomes read-only when security violations are detected
709
-
710
- ```javascript
711
- // Get security status
712
- const info = bridge.getPageInfo();
713
- console.log(info.security);
714
- // { sandboxActive: true, locked: false, sessionToken: "a3f2..." }
715
-
716
- // View audit log
717
- const audit = bridge.security.getAuditLog(20);
718
- ```
719
-
720
- ### Selector Restrictions
721
-
722
- Block sensitive page sections from agent access:
723
-
724
- ```javascript
725
- window.AIBridgeConfig = {
726
- restrictions: {
727
- blockedSelectors: [".private", "[data-private]", "#payment-form"],
728
- allowedSelectors: [".public-content"]
729
- }
730
- };
731
- ```
732
-
733
- ---
734
-
735
- ## Self-Healing Selectors
736
-
737
- Modern SPAs frequently change their DOM structure. WAB's self-healing system ensures selectors keep working even when the page changes:
738
-
739
- ### How It Works
740
-
741
- 1. **Fingerprinting** — When actions are discovered, WAB stores a rich fingerprint of each element (tag, id, classes, text, ARIA attributes, position)
742
- 2. **7-Strategy Resolution** — When a selector breaks, WAB tries these strategies in order:
743
- - `data-wab-id` attribute (most stable — add to your HTML)
744
- - `data-testid` attribute
745
- - Element ID
746
- - `aria-label` (semantic, usually survives redesigns)
747
- - `name` attribute
748
- - Fuzzy text matching (bigram similarity > 70%)
749
- - Role + position heuristic
750
- 3. **SPA Observer** — A `MutationObserver` watches for DOM changes and automatically re-discovers actions with a 500ms debounce
751
-
752
- ```javascript
753
- // Check healing stats
754
- const info = bridge.getPageInfo();
755
- console.log(info.selfHealing);
756
- // { tracked: 12, healed: 3, failed: 0 }
757
-
758
- // Listen for healing events
759
- bridge.events.on('selector:healed', (data) => {
760
- console.log(`Healed: ${data.action} via ${data.strategy}`);
761
- });
762
- ```
763
-
764
- ### Best Practices for Site Owners
765
-
766
- Add `data-wab-id` attributes to critical elements for maximum stability:
767
-
768
- ```html
769
- <button data-wab-id="signup-btn">Sign Up</button>
770
- <form data-wab-id="login-form">...</form>
771
- ```
772
-
773
- ---
774
-
775
- ## Stealth Mode
776
-
777
- For sites with anti-bot protection, WAB can simulate human-like interaction patterns. **Stealth mode requires explicit consent** to ensure ethical use.
778
-
779
- ```javascript
780
- window.AIBridgeConfig = {
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
+ [![npm](https://img.shields.io/npm/v/web-agent-bridge)](https://www.npmjs.com/package/web-agent-bridge)
4
+ [![CI](https://github.com/abokenan444/web-agent-bridge/actions/workflows/ci.yml/badge.svg)](https://github.com/abokenan444/web-agent-bridge/actions/workflows/ci.yml)
5
+ [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)
6
+ [![Node.js](https://img.shields.io/badge/node-%3E%3D18-brightgreen.svg)](https://nodejs.org/)
7
+ [![Docker](https://img.shields.io/badge/docker-ready-blue.svg)](https://hub.docker.com/)
8
+ [![PRs Welcome](https://img.shields.io/badge/PRs-welcome-brightgreen.svg)](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.