web-agent-bridge 2.2.0 → 2.3.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (39) hide show
  1. package/README.ar.md +7 -0
  2. package/README.md +7 -0
  3. package/package.json +12 -4
  4. package/public/commander-dashboard.html +243 -0
  5. package/public/css/premium.css +317 -317
  6. package/public/demo.html +259 -259
  7. package/public/index.html +644 -592
  8. package/public/llms.txt +1 -0
  9. package/public/mesh-dashboard.html +328 -0
  10. package/public/premium-dashboard.html +2487 -2487
  11. package/public/premium.html +791 -791
  12. package/public/script/wab.min.js +181 -6
  13. package/script/ai-agent-bridge.js +196 -0
  14. package/sdk/agent-mesh.js +449 -0
  15. package/sdk/commander.js +262 -0
  16. package/sdk/index.js +260 -259
  17. package/sdk/package.json +1 -1
  18. package/server/index.js +13 -1
  19. package/server/migrations/002_premium_features.sql +418 -418
  20. package/server/models/db.js +24 -5
  21. package/server/routes/admin-premium.js +671 -671
  22. package/server/routes/commander.js +316 -0
  23. package/server/routes/mesh.js +469 -0
  24. package/server/routes/premium-v2.js +686 -686
  25. package/server/routes/premium.js +724 -724
  26. package/server/services/agent-learning.js +575 -0
  27. package/server/services/agent-memory.js +625 -625
  28. package/server/services/agent-mesh.js +539 -0
  29. package/server/services/agent-symphony.js +711 -0
  30. package/server/services/commander.js +738 -0
  31. package/server/services/edge-compute.js +440 -0
  32. package/server/services/local-ai.js +389 -0
  33. package/server/services/plugins.js +747 -747
  34. package/server/services/self-healing.js +843 -843
  35. package/server/services/swarm.js +788 -788
  36. package/server/services/vision.js +871 -871
  37. package/public/admin/dashboard.html +0 -848
  38. package/public/admin/login.html +0 -84
  39. package/public/video/tutorial.mp4 +0 -0
package/sdk/index.js CHANGED
@@ -1,259 +1,260 @@
1
- /**
2
- * WAB Agent SDK
3
- *
4
- * Helpers for building AI agents that interact with Web Agent Bridge.
5
- * Works with Puppeteer, Playwright, or any browser automation tool.
6
- *
7
- * Usage:
8
- * const { WABAgent } = require('./sdk');
9
- * const agent = new WABAgent(page);
10
- * await agent.waitForBridge();
11
- * const actions = await agent.getActions();
12
- * await agent.execute('signup', { email: 'test@example.com' });
13
- */
14
-
15
- class WABAgent {
16
- /**
17
- * @param {object} page — A Puppeteer or Playwright page object
18
- * @param {object} [options]
19
- * @param {number} [options.timeout=10000] — Default timeout in ms
20
- * @param {boolean} [options.useBiDi=false] — Use BiDi interface instead of AICommands
21
- */
22
- constructor(page, options = {}) {
23
- this.page = page;
24
- this.timeout = options.timeout || 10000;
25
- this.useBiDi = options.useBiDi || false;
26
- this._biDiId = 0;
27
- }
28
-
29
- /**
30
- * Wait for the WAB bridge to be ready on the page.
31
- * @returns {Promise<boolean>}
32
- */
33
- async waitForBridge() {
34
- const iface = this.useBiDi ? '__wab_bidi' : 'AICommands';
35
- await this.page.waitForFunction(
36
- (name) => typeof window[name] !== 'undefined',
37
- { timeout: this.timeout },
38
- iface
39
- );
40
- return true;
41
- }
42
-
43
- /**
44
- * Check if the bridge is loaded on the current page.
45
- * @returns {Promise<boolean>}
46
- */
47
- async hasBridge() {
48
- const iface = this.useBiDi ? '__wab_bidi' : 'AICommands';
49
- return this.page.evaluate((name) => typeof window[name] !== 'undefined', iface);
50
- }
51
-
52
- /**
53
- * Get all available actions.
54
- * @param {string} [category] — Optional category filter
55
- * @returns {Promise<Array>}
56
- */
57
- async getActions(category) {
58
- if (this.useBiDi) {
59
- const result = await this._bidiSend('wab.getActions', category ? { category } : {});
60
- return result.result || [];
61
- }
62
- return this.page.evaluate((cat) => window.AICommands.getActions(cat), category);
63
- }
64
-
65
- /**
66
- * Get a single action by name.
67
- * @param {string} name
68
- * @returns {Promise<object|null>}
69
- */
70
- async getAction(name) {
71
- return this.page.evaluate((n) => window.AICommands.getAction(n), name);
72
- }
73
-
74
- /**
75
- * Execute an action by name.
76
- * @param {string} name — Action name
77
- * @param {object} [params] — Action parameters
78
- * @returns {Promise<object>}
79
- */
80
- async execute(name, params) {
81
- if (this.useBiDi) {
82
- const result = await this._bidiSend('wab.executeAction', { name, data: params || {} });
83
- return result.result || result;
84
- }
85
- return this.page.evaluate(
86
- (n, p) => window.AICommands.execute(n, p),
87
- name, params
88
- );
89
- }
90
-
91
- /**
92
- * Read text content of an element.
93
- * @param {string} selector — CSS selector
94
- * @returns {Promise<object>}
95
- */
96
- async readContent(selector) {
97
- if (this.useBiDi) {
98
- const result = await this._bidiSend('wab.readContent', { selector });
99
- return result.result || result;
100
- }
101
- return this.page.evaluate((sel) => window.AICommands.readContent(sel), selector);
102
- }
103
-
104
- /**
105
- * Get page info and bridge metadata.
106
- * @returns {Promise<object>}
107
- */
108
- async getPageInfo() {
109
- if (this.useBiDi) {
110
- const result = await this._bidiSend('wab.getPageInfo');
111
- return result.result || result;
112
- }
113
- return this.page.evaluate(() => window.AICommands.getPageInfo());
114
- }
115
-
116
- /**
117
- * Authenticate an agent with the bridge.
118
- * @param {string} apiKey
119
- * @param {object} [meta] — Agent metadata
120
- * @returns {Promise<object>}
121
- */
122
- async authenticate(apiKey, meta) {
123
- return this.page.evaluate(
124
- (key, m) => window.AICommands.authenticate(key, m),
125
- apiKey, meta
126
- );
127
- }
128
-
129
- /**
130
- * Navigate to a URL and wait for the bridge.
131
- * @param {string} url
132
- * @returns {Promise<void>}
133
- */
134
- async navigateAndWait(url) {
135
- await this.page.goto(url, { waitUntil: 'networkidle2' });
136
- await this.waitForBridge();
137
- }
138
-
139
- /**
140
- * Execute multiple actions in sequence.
141
- * @param {Array<{name: string, params?: object}>} steps
142
- * @returns {Promise<Array>}
143
- */
144
- async executeSteps(steps) {
145
- const results = [];
146
- for (const step of steps) {
147
- results.push(await this.execute(step.name, step.params));
148
- }
149
- return results;
150
- }
151
-
152
- /**
153
- * Get BiDi context (only available when useBiDi is true).
154
- * @returns {Promise<object>}
155
- */
156
- async getBiDiContext() {
157
- return this.page.evaluate(() => window.__wab_bidi.getContext());
158
- }
159
-
160
- /**
161
- * Check if the page has granted consent for agent interactions.
162
- * @returns {Promise<boolean>}
163
- */
164
- async hasConsent() {
165
- return this.page.evaluate(() => {
166
- if (typeof window.WABConsent !== 'undefined') return window.WABConsent.hasConsent();
167
- // If no consent script, treat as allowed
168
- return true;
169
- });
170
- }
171
-
172
- /**
173
- * Wait until consent is granted (blocks until user clicks Allow).
174
- * @param {number} [pollMs=500]
175
- * @returns {Promise<boolean>}
176
- */
177
- async waitForConsent(pollMs = 500) {
178
- return this.page.waitForFunction(
179
- () => {
180
- if (typeof window.WABConsent === 'undefined') return true;
181
- return window.WABConsent.hasConsent();
182
- },
183
- { timeout: this.timeout, polling: pollMs }
184
- ).then(() => true);
185
- }
186
-
187
- /**
188
- * Discover the page and return the list of actions.
189
- * Combines bridge discovery with runtime getActions().
190
- * @returns {Promise<object>}
191
- */
192
- async discover() {
193
- return this.page.evaluate(() => {
194
- if (window.WAB && typeof window.WAB.discover === 'function') return window.WAB.discover();
195
- if (window.AICommands && typeof window.AICommands.getActions === 'function') {
196
- return { actions: window.AICommands.getActions(), meta: window.AICommands.getPageInfo ? window.AICommands.getPageInfo() : {} };
197
- }
198
- return { actions: [] };
199
- });
200
- }
201
-
202
- /**
203
- * Run a sequence of actions, stopping on the first failure.
204
- * @param {Array<{name: string, params?: object}>} steps
205
- * @param {{ stopOnError?: boolean }} [options]
206
- * @returns {Promise<Array<{ name: string, ok: boolean, result?: any, error?: string }>>}
207
- */
208
- async runPipeline(steps, options = {}) {
209
- const stopOnError = options.stopOnError !== false;
210
- const results = [];
211
- for (const step of steps) {
212
- try {
213
- const res = await this.execute(step.name, step.params);
214
- results.push({ name: step.name, ok: true, result: res });
215
- } catch (err) {
216
- results.push({ name: step.name, ok: false, error: err.message || String(err) });
217
- if (stopOnError) break;
218
- }
219
- }
220
- return results;
221
- }
222
-
223
- /**
224
- * Execute multiple actions in parallel.
225
- * @param {Array<{name: string, params?: object}>} actions
226
- * @returns {Promise<Array<{ name: string, status: string, value?: any, reason?: string }>>}
227
- */
228
- async executeParallel(actions) {
229
- const promises = actions.map((a) =>
230
- this.execute(a.name, a.params)
231
- .then((value) => ({ name: a.name, status: 'fulfilled', value }))
232
- .catch((err) => ({ name: a.name, status: 'rejected', reason: err.message || String(err) }))
233
- );
234
- return Promise.all(promises);
235
- }
236
-
237
- /**
238
- * Take a screenshot and return as base64 (useful for vision agents).
239
- * @param {{ fullPage?: boolean }} [opts]
240
- * @returns {Promise<string>}
241
- */
242
- async screenshot(opts = {}) {
243
- const buf = await this.page.screenshot({
244
- encoding: 'base64',
245
- fullPage: opts.fullPage || false
246
- });
247
- return buf;
248
- }
249
-
250
- /** @private */
251
- async _bidiSend(method, params = {}) {
252
- const cmd = { id: ++this._biDiId, method, params };
253
- return this.page.evaluate((c) => window.__wab_bidi.send(c), cmd);
254
- }
255
- }
256
-
257
- const { WABMultiAgent } = require('./multi-agent');
258
-
259
- module.exports = { WABAgent, WABMultiAgent };
1
+ /**
2
+ * WAB Agent SDK
3
+ *
4
+ * Helpers for building AI agents that interact with Web Agent Bridge.
5
+ * Works with Puppeteer, Playwright, or any browser automation tool.
6
+ *
7
+ * Usage:
8
+ * const { WABAgent } = require('./sdk');
9
+ * const agent = new WABAgent(page);
10
+ * await agent.waitForBridge();
11
+ * const actions = await agent.getActions();
12
+ * await agent.execute('signup', { email: 'test@example.com' });
13
+ */
14
+
15
+ class WABAgent {
16
+ /**
17
+ * @param {object} page — A Puppeteer or Playwright page object
18
+ * @param {object} [options]
19
+ * @param {number} [options.timeout=10000] — Default timeout in ms
20
+ * @param {boolean} [options.useBiDi=false] — Use BiDi interface instead of AICommands
21
+ */
22
+ constructor(page, options = {}) {
23
+ this.page = page;
24
+ this.timeout = options.timeout || 10000;
25
+ this.useBiDi = options.useBiDi || false;
26
+ this._biDiId = 0;
27
+ }
28
+
29
+ /**
30
+ * Wait for the WAB bridge to be ready on the page.
31
+ * @returns {Promise<boolean>}
32
+ */
33
+ async waitForBridge() {
34
+ const iface = this.useBiDi ? '__wab_bidi' : 'AICommands';
35
+ await this.page.waitForFunction(
36
+ (name) => typeof window[name] !== 'undefined',
37
+ { timeout: this.timeout },
38
+ iface
39
+ );
40
+ return true;
41
+ }
42
+
43
+ /**
44
+ * Check if the bridge is loaded on the current page.
45
+ * @returns {Promise<boolean>}
46
+ */
47
+ async hasBridge() {
48
+ const iface = this.useBiDi ? '__wab_bidi' : 'AICommands';
49
+ return this.page.evaluate((name) => typeof window[name] !== 'undefined', iface);
50
+ }
51
+
52
+ /**
53
+ * Get all available actions.
54
+ * @param {string} [category] — Optional category filter
55
+ * @returns {Promise<Array>}
56
+ */
57
+ async getActions(category) {
58
+ if (this.useBiDi) {
59
+ const result = await this._bidiSend('wab.getActions', category ? { category } : {});
60
+ return result.result || [];
61
+ }
62
+ return this.page.evaluate((cat) => window.AICommands.getActions(cat), category);
63
+ }
64
+
65
+ /**
66
+ * Get a single action by name.
67
+ * @param {string} name
68
+ * @returns {Promise<object|null>}
69
+ */
70
+ async getAction(name) {
71
+ return this.page.evaluate((n) => window.AICommands.getAction(n), name);
72
+ }
73
+
74
+ /**
75
+ * Execute an action by name.
76
+ * @param {string} name — Action name
77
+ * @param {object} [params] — Action parameters
78
+ * @returns {Promise<object>}
79
+ */
80
+ async execute(name, params) {
81
+ if (this.useBiDi) {
82
+ const result = await this._bidiSend('wab.executeAction', { name, data: params || {} });
83
+ return result.result || result;
84
+ }
85
+ return this.page.evaluate(
86
+ (n, p) => window.AICommands.execute(n, p),
87
+ name, params
88
+ );
89
+ }
90
+
91
+ /**
92
+ * Read text content of an element.
93
+ * @param {string} selector — CSS selector
94
+ * @returns {Promise<object>}
95
+ */
96
+ async readContent(selector) {
97
+ if (this.useBiDi) {
98
+ const result = await this._bidiSend('wab.readContent', { selector });
99
+ return result.result || result;
100
+ }
101
+ return this.page.evaluate((sel) => window.AICommands.readContent(sel), selector);
102
+ }
103
+
104
+ /**
105
+ * Get page info and bridge metadata.
106
+ * @returns {Promise<object>}
107
+ */
108
+ async getPageInfo() {
109
+ if (this.useBiDi) {
110
+ const result = await this._bidiSend('wab.getPageInfo');
111
+ return result.result || result;
112
+ }
113
+ return this.page.evaluate(() => window.AICommands.getPageInfo());
114
+ }
115
+
116
+ /**
117
+ * Authenticate an agent with the bridge.
118
+ * @param {string} apiKey
119
+ * @param {object} [meta] — Agent metadata
120
+ * @returns {Promise<object>}
121
+ */
122
+ async authenticate(apiKey, meta) {
123
+ return this.page.evaluate(
124
+ (key, m) => window.AICommands.authenticate(key, m),
125
+ apiKey, meta
126
+ );
127
+ }
128
+
129
+ /**
130
+ * Navigate to a URL and wait for the bridge.
131
+ * @param {string} url
132
+ * @returns {Promise<void>}
133
+ */
134
+ async navigateAndWait(url) {
135
+ await this.page.goto(url, { waitUntil: 'networkidle2' });
136
+ await this.waitForBridge();
137
+ }
138
+
139
+ /**
140
+ * Execute multiple actions in sequence.
141
+ * @param {Array<{name: string, params?: object}>} steps
142
+ * @returns {Promise<Array>}
143
+ */
144
+ async executeSteps(steps) {
145
+ const results = [];
146
+ for (const step of steps) {
147
+ results.push(await this.execute(step.name, step.params));
148
+ }
149
+ return results;
150
+ }
151
+
152
+ /**
153
+ * Get BiDi context (only available when useBiDi is true).
154
+ * @returns {Promise<object>}
155
+ */
156
+ async getBiDiContext() {
157
+ return this.page.evaluate(() => window.__wab_bidi.getContext());
158
+ }
159
+
160
+ /**
161
+ * Check if the page has granted consent for agent interactions.
162
+ * @returns {Promise<boolean>}
163
+ */
164
+ async hasConsent() {
165
+ return this.page.evaluate(() => {
166
+ if (typeof window.WABConsent !== 'undefined') return window.WABConsent.hasConsent();
167
+ // If no consent script, treat as allowed
168
+ return true;
169
+ });
170
+ }
171
+
172
+ /**
173
+ * Wait until consent is granted (blocks until user clicks Allow).
174
+ * @param {number} [pollMs=500]
175
+ * @returns {Promise<boolean>}
176
+ */
177
+ async waitForConsent(pollMs = 500) {
178
+ return this.page.waitForFunction(
179
+ () => {
180
+ if (typeof window.WABConsent === 'undefined') return true;
181
+ return window.WABConsent.hasConsent();
182
+ },
183
+ { timeout: this.timeout, polling: pollMs }
184
+ ).then(() => true);
185
+ }
186
+
187
+ /**
188
+ * Discover the page and return the list of actions.
189
+ * Combines bridge discovery with runtime getActions().
190
+ * @returns {Promise<object>}
191
+ */
192
+ async discover() {
193
+ return this.page.evaluate(() => {
194
+ if (window.WAB && typeof window.WAB.discover === 'function') return window.WAB.discover();
195
+ if (window.AICommands && typeof window.AICommands.getActions === 'function') {
196
+ return { actions: window.AICommands.getActions(), meta: window.AICommands.getPageInfo ? window.AICommands.getPageInfo() : {} };
197
+ }
198
+ return { actions: [] };
199
+ });
200
+ }
201
+
202
+ /**
203
+ * Run a sequence of actions, stopping on the first failure.
204
+ * @param {Array<{name: string, params?: object}>} steps
205
+ * @param {{ stopOnError?: boolean }} [options]
206
+ * @returns {Promise<Array<{ name: string, ok: boolean, result?: any, error?: string }>>}
207
+ */
208
+ async runPipeline(steps, options = {}) {
209
+ const stopOnError = options.stopOnError !== false;
210
+ const results = [];
211
+ for (const step of steps) {
212
+ try {
213
+ const res = await this.execute(step.name, step.params);
214
+ results.push({ name: step.name, ok: true, result: res });
215
+ } catch (err) {
216
+ results.push({ name: step.name, ok: false, error: err.message || String(err) });
217
+ if (stopOnError) break;
218
+ }
219
+ }
220
+ return results;
221
+ }
222
+
223
+ /**
224
+ * Execute multiple actions in parallel.
225
+ * @param {Array<{name: string, params?: object}>} actions
226
+ * @returns {Promise<Array<{ name: string, status: string, value?: any, reason?: string }>>}
227
+ */
228
+ async executeParallel(actions) {
229
+ const promises = actions.map((a) =>
230
+ this.execute(a.name, a.params)
231
+ .then((value) => ({ name: a.name, status: 'fulfilled', value }))
232
+ .catch((err) => ({ name: a.name, status: 'rejected', reason: err.message || String(err) }))
233
+ );
234
+ return Promise.all(promises);
235
+ }
236
+
237
+ /**
238
+ * Take a screenshot and return as base64 (useful for vision agents).
239
+ * @param {{ fullPage?: boolean }} [opts]
240
+ * @returns {Promise<string>}
241
+ */
242
+ async screenshot(opts = {}) {
243
+ const buf = await this.page.screenshot({
244
+ encoding: 'base64',
245
+ fullPage: opts.fullPage || false
246
+ });
247
+ return buf;
248
+ }
249
+
250
+ /** @private */
251
+ async _bidiSend(method, params = {}) {
252
+ const cmd = { id: ++this._biDiId, method, params };
253
+ return this.page.evaluate((c) => window.__wab_bidi.send(c), cmd);
254
+ }
255
+ }
256
+
257
+ const { WABMultiAgent } = require('./multi-agent');
258
+ const { WABAgentMesh } = require('./agent-mesh');
259
+
260
+ module.exports = { WABAgent, WABMultiAgent, WABAgentMesh };
package/sdk/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "web-agent-bridge-sdk",
3
- "version": "2.2.0",
3
+ "version": "2.3.0",
4
4
  "description": "SDK for building AI agents that interact with Web Agent Bridge (WAB)",
5
5
  "main": "index.js",
6
6
  "license": "MIT",
package/server/index.js CHANGED
@@ -19,6 +19,8 @@ const licenseRoutes = require('./routes/license');
19
19
  const adminRoutes = require('./routes/admin');
20
20
  const billingRoutes = require('./routes/billing');
21
21
  const sovereignRoutes = require('./routes/sovereign');
22
+ const meshRoutes = require('./routes/mesh');
23
+ const commanderRoutes = require('./routes/commander');
22
24
  const { handleWebhookRequest } = require('./services/stripe');
23
25
 
24
26
  const app = express();
@@ -59,6 +61,7 @@ app.use(
59
61
  directives: {
60
62
  defaultSrc: ["'self'"],
61
63
  scriptSrc,
64
+ scriptSrcAttr: scriptSrc,
62
65
  styleSrc,
63
66
  imgSrc: ["'self'", 'data:', 'https:'],
64
67
  connectSrc: ["'self'", 'ws:', 'wss:'],
@@ -66,7 +69,8 @@ app.use(
66
69
  frameSrc: ["'none'"],
67
70
  frameAncestors: ["'none'"],
68
71
  objectSrc: ["'none'"],
69
- baseUri: ["'self'"]
72
+ baseUri: ["'self'"],
73
+ formAction: ["'self'"]
70
74
  }
71
75
  },
72
76
  crossOriginEmbedderPolicy: false
@@ -113,10 +117,18 @@ app.use('/api/license', licenseLimiter, licenseRoutes);
113
117
  app.use('/api/admin', apiLimiter, adminRoutes);
114
118
  app.use('/api/billing', apiLimiter, billingRoutes);
115
119
  app.use('/api/sovereign', apiLimiter, sovereignRoutes);
120
+ app.use('/api/mesh', apiLimiter, meshRoutes);
121
+ app.use('/api/commander', apiLimiter, commanderRoutes);
116
122
 
117
123
  app.get('/dashboard', (req, res) => {
118
124
  res.sendFile(path.join(__dirname, '..', 'public', 'dashboard.html'));
119
125
  });
126
+ app.get('/mesh-dashboard', (req, res) => {
127
+ res.sendFile(path.join(__dirname, '..', 'public', 'mesh-dashboard.html'));
128
+ });
129
+ app.get('/commander-dashboard', (req, res) => {
130
+ res.sendFile(path.join(__dirname, '..', 'public', 'commander-dashboard.html'));
131
+ });
120
132
  app.get('/docs', (req, res) => {
121
133
  res.sendFile(path.join(__dirname, '..', 'public', 'docs.html'));
122
134
  });