web-agent-bridge 2.0.0 → 2.1.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.
@@ -0,0 +1,660 @@
1
+ <!DOCTYPE html>
2
+ <html lang="en" dir="ltr">
3
+ <head>
4
+ <meta charset="UTF-8">
5
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
6
+ <title>Digital Fortress — Sovereign Dashboard | Web Agent Bridge</title>
7
+ <style>
8
+ :root {
9
+ --bg-primary: #0a0e1a;
10
+ --bg-secondary: #111827;
11
+ --bg-card: #1a2035;
12
+ --bg-card-hover: #1e2744;
13
+ --accent-blue: #3b82f6;
14
+ --accent-green: #10b981;
15
+ --accent-amber: #f59e0b;
16
+ --accent-red: #ef4444;
17
+ --accent-purple: #8b5cf6;
18
+ --accent-cyan: #06b6d4;
19
+ --text-primary: #f1f5f9;
20
+ --text-secondary: #94a3b8;
21
+ --text-muted: #475569;
22
+ --border: #1e293b;
23
+ --glow-blue: 0 0 20px rgba(59,130,246,0.3);
24
+ --glow-green: 0 0 20px rgba(16,185,129,0.3);
25
+ --glow-red: 0 0 20px rgba(239,68,68,0.3);
26
+ --radius: 12px;
27
+ }
28
+ * { margin: 0; padding: 0; box-sizing: border-box; }
29
+ body {
30
+ font-family: 'Segoe UI', system-ui, -apple-system, sans-serif;
31
+ background: var(--bg-primary);
32
+ color: var(--text-primary);
33
+ min-height: 100vh;
34
+ }
35
+ .header {
36
+ background: linear-gradient(135deg, var(--bg-secondary) 0%, var(--bg-primary) 100%);
37
+ border-bottom: 1px solid var(--border);
38
+ padding: 1rem 2rem;
39
+ display: flex; align-items: center; justify-content: space-between;
40
+ }
41
+ .header-logo { display: flex; align-items: center; gap: 12px; }
42
+ .header-logo svg { width: 36px; height: 36px; }
43
+ .header-logo h1 { font-size: 1.25rem; font-weight: 700; }
44
+ .header-logo span { color: var(--accent-blue); }
45
+ .header-status {
46
+ display: flex; align-items: center; gap: 8px;
47
+ background: rgba(16,185,129,0.1); border: 1px solid rgba(16,185,129,0.3);
48
+ padding: 6px 14px; border-radius: 20px; font-size: 0.85rem;
49
+ }
50
+ .status-dot {
51
+ width: 8px; height: 8px; border-radius: 50%;
52
+ background: var(--accent-green);
53
+ animation: pulse 2s infinite;
54
+ }
55
+ @keyframes pulse {
56
+ 0%, 100% { opacity: 1; box-shadow: 0 0 0 0 rgba(16,185,129,0.5); }
57
+ 50% { opacity: 0.7; box-shadow: 0 0 0 6px rgba(16,185,129,0); }
58
+ }
59
+ .container { max-width: 1400px; margin: 0 auto; padding: 1.5rem; }
60
+ .stats-row { display: grid; grid-template-columns: repeat(auto-fit, minmax(200px, 1fr)); gap: 1rem; margin-bottom: 1.5rem; }
61
+ .stat-card {
62
+ background: var(--bg-card); border: 1px solid var(--border);
63
+ border-radius: var(--radius); padding: 1.25rem; transition: all 0.3s;
64
+ position: relative; overflow: hidden;
65
+ }
66
+ .stat-card:hover { background: var(--bg-card-hover); transform: translateY(-2px); }
67
+ .stat-card::before {
68
+ content: ''; position: absolute; top: 0; left: 0;
69
+ width: 80px; height: 80px; border-radius: 50%;
70
+ opacity: 0.05; transform: translate(-20px, -20px);
71
+ }
72
+ .stat-card.blue::before { background: var(--accent-blue); }
73
+ .stat-card.green::before { background: var(--accent-green); }
74
+ .stat-card.amber::before { background: var(--accent-amber); }
75
+ .stat-card.red::before { background: var(--accent-red); }
76
+ .stat-card.purple::before { background: var(--accent-purple); }
77
+ .stat-card.cyan::before { background: var(--accent-cyan); }
78
+ .stat-label { font-size: 0.8rem; color: var(--text-secondary); margin-bottom: 4px; }
79
+ .stat-value { font-size: 1.8rem; font-weight: 700; }
80
+ .stat-value.blue { color: var(--accent-blue); }
81
+ .stat-value.green { color: var(--accent-green); }
82
+ .stat-value.amber { color: var(--accent-amber); }
83
+ .stat-value.red { color: var(--accent-red); }
84
+ .stat-value.purple { color: var(--accent-purple); }
85
+ .stat-value.cyan { color: var(--accent-cyan); }
86
+ .stat-sub { font-size: 0.75rem; color: var(--text-muted); margin-top: 4px; }
87
+ .dashboard-grid { display: grid; grid-template-columns: 1fr 1fr; gap: 1.5rem; margin-bottom: 1.5rem; }
88
+ @media (max-width: 900px) { .dashboard-grid { grid-template-columns: 1fr; } }
89
+ .full-width { grid-column: 1 / -1; }
90
+ .panel {
91
+ background: var(--bg-card); border: 1px solid var(--border);
92
+ border-radius: var(--radius); overflow: hidden;
93
+ }
94
+ .panel-header {
95
+ padding: 1rem 1.25rem; border-bottom: 1px solid var(--border);
96
+ display: flex; align-items: center; justify-content: space-between;
97
+ }
98
+ .panel-title { font-size: 1rem; font-weight: 600; display: flex; align-items: center; gap: 8px; }
99
+ .panel-badge {
100
+ font-size: 0.7rem; padding: 2px 8px; border-radius: 10px;
101
+ background: rgba(59,130,246,0.15); color: var(--accent-blue);
102
+ }
103
+ .panel-body { padding: 1.25rem; }
104
+ .shield-radar {
105
+ display: flex; align-items: center; justify-content: center;
106
+ position: relative; height: 260px;
107
+ }
108
+ .radar-ring {
109
+ position: absolute; border-radius: 50%;
110
+ border: 1px solid rgba(59,130,246,0.15);
111
+ }
112
+ .radar-ring:nth-child(1) { width: 240px; height: 240px; }
113
+ .radar-ring:nth-child(2) { width: 180px; height: 180px; }
114
+ .radar-ring:nth-child(3) { width: 120px; height: 120px; }
115
+ .radar-center {
116
+ position: relative; z-index: 2;
117
+ width: 100px; height: 100px; border-radius: 50%;
118
+ display: flex; flex-direction: column; align-items: center; justify-content: center;
119
+ font-weight: 700; font-size: 1.6rem;
120
+ transition: all 0.5s;
121
+ }
122
+ .radar-center.safe { background: rgba(16,185,129,0.15); border: 2px solid var(--accent-green); color: var(--accent-green); box-shadow: var(--glow-green); }
123
+ .radar-center.warn { background: rgba(245,158,11,0.15); border: 2px solid var(--accent-amber); color: var(--accent-amber); }
124
+ .radar-center.danger { background: rgba(239,68,68,0.15); border: 2px solid var(--accent-red); color: var(--accent-red); box-shadow: var(--glow-red); }
125
+ .radar-center small { font-size: 0.65rem; font-weight: 400; color: var(--text-secondary); }
126
+ .radar-dot {
127
+ position: absolute; width: 8px; height: 8px; border-radius: 50%;
128
+ animation: radarBlink 3s infinite;
129
+ }
130
+ .radar-dot.green { background: var(--accent-green); }
131
+ .radar-dot.amber { background: var(--accent-amber); }
132
+ .radar-dot.red { background: var(--accent-red); }
133
+ @keyframes radarBlink {
134
+ 0%, 100% { opacity: 1; } 50% { opacity: 0.3; }
135
+ }
136
+ .rep-bar-container { margin: 0.75rem 0; }
137
+ .rep-bar-label { display: flex; justify-content: space-between; font-size: 0.8rem; margin-bottom: 4px; color: var(--text-secondary); }
138
+ .rep-bar-track { height: 8px; background: var(--bg-primary); border-radius: 4px; overflow: hidden; }
139
+ .rep-bar-fill { height: 100%; border-radius: 4px; transition: width 1s ease; }
140
+ .rep-bar-fill.blue { background: linear-gradient(90deg, var(--accent-blue), var(--accent-cyan)); }
141
+ .rep-bar-fill.green { background: linear-gradient(90deg, var(--accent-green), #34d399); }
142
+ .rep-bar-fill.amber { background: linear-gradient(90deg, var(--accent-amber), #fbbf24); }
143
+ .neg-timeline { list-style: none; }
144
+ .neg-item {
145
+ padding: 0.75rem 0; border-bottom: 1px solid var(--border);
146
+ display: flex; align-items: flex-start; gap: 12px;
147
+ }
148
+ .neg-item:last-child { border-bottom: none; }
149
+ .neg-icon {
150
+ width: 36px; height: 36px; border-radius: 50%;
151
+ display: flex; align-items: center; justify-content: center; flex-shrink: 0;
152
+ font-size: 1rem;
153
+ }
154
+ .neg-icon.deal { background: rgba(16,185,129,0.15); color: var(--accent-green); }
155
+ .neg-icon.pending { background: rgba(245,158,11,0.15); color: var(--accent-amber); }
156
+ .neg-icon.rejected { background: rgba(239,68,68,0.15); color: var(--accent-red); }
157
+ .neg-details { flex: 1; }
158
+ .neg-title { font-size: 0.85rem; font-weight: 500; }
159
+ .neg-meta { font-size: 0.75rem; color: var(--text-muted); margin-top: 2px; }
160
+ .neg-savings { font-weight: 600; color: var(--accent-green); }
161
+ .check-list { list-style: none; }
162
+ .check-item {
163
+ padding: 0.6rem 0; border-bottom: 1px solid var(--border);
164
+ display: flex; align-items: center; gap: 10px; font-size: 0.85rem;
165
+ }
166
+ .check-item:last-child { border-bottom: none; }
167
+ .check-badge {
168
+ padding: 2px 8px; border-radius: 6px; font-size: 0.7rem; font-weight: 600;
169
+ }
170
+ .check-badge.pass { background: rgba(16,185,129,0.15); color: var(--accent-green); }
171
+ .check-badge.warn { background: rgba(245,158,11,0.15); color: var(--accent-amber); }
172
+ .check-badge.fail { background: rgba(239,68,68,0.15); color: var(--accent-red); }
173
+ .sites-table { width: 100%; border-collapse: collapse; }
174
+ .sites-table th { text-align: left; font-size: 0.75rem; color: var(--text-muted); padding: 0.5rem 0.75rem; border-bottom: 1px solid var(--border); font-weight: 500; }
175
+ .sites-table td { padding: 0.75rem; border-bottom: 1px solid var(--border); font-size: 0.85rem; }
176
+ .sites-table tr:last-child td { border-bottom: none; }
177
+ .sites-table tr:hover td { background: rgba(59,130,246,0.05); }
178
+ .trust-badge {
179
+ display: inline-block; padding: 2px 10px; border-radius: 10px;
180
+ font-size: 0.7rem; font-weight: 600;
181
+ }
182
+ .trust-badge.exemplary { background: rgba(16,185,129,0.15); color: var(--accent-green); }
183
+ .trust-badge.verified { background: rgba(59,130,246,0.15); color: var(--accent-blue); }
184
+ .trust-badge.trusted { background: rgba(139,92,246,0.15); color: var(--accent-purple); }
185
+ .trust-badge.emerging { background: rgba(245,158,11,0.15); color: var(--accent-amber); }
186
+ .trust-badge.unknown { background: rgba(71,85,105,0.15); color: var(--text-muted); }
187
+ .trust-badge.suspicious { background: rgba(239,68,68,0.15); color: var(--accent-red); }
188
+ .privacy-meter { display: flex; flex-direction: column; gap: 1rem; }
189
+ .privacy-row { display: flex; align-items: center; gap: 12px; }
190
+ .privacy-icon { font-size: 1.5rem; width: 40px; text-align: center; }
191
+ .privacy-info { flex: 1; }
192
+ .privacy-label { font-size: 0.85rem; font-weight: 500; }
193
+ .privacy-desc { font-size: 0.75rem; color: var(--text-muted); }
194
+ .privacy-count { font-size: 1.1rem; font-weight: 700; color: var(--accent-cyan); }
195
+ .model-switcher { display: flex; gap: 8px; flex-wrap: wrap; }
196
+ .model-btn {
197
+ padding: 8px 16px; border-radius: 8px; border: 1px solid var(--border);
198
+ background: transparent; color: var(--text-secondary);
199
+ cursor: pointer; font-size: 0.8rem; transition: all 0.2s;
200
+ }
201
+ .model-btn:hover { border-color: var(--accent-blue); color: var(--text-primary); }
202
+ .model-btn.active {
203
+ background: rgba(59,130,246,0.15); border-color: var(--accent-blue);
204
+ color: var(--accent-blue); font-weight: 600;
205
+ }
206
+ .empty-state { text-align: center; padding: 2rem; color: var(--text-muted); }
207
+ .empty-state p { font-size: 0.85rem; }
208
+ .loading { display: flex; align-items: center; justify-content: center; padding: 3rem; }
209
+ .spinner {
210
+ width: 36px; height: 36px; border: 3px solid var(--border);
211
+ border-top-color: var(--accent-blue); border-radius: 50%;
212
+ animation: spin 0.8s linear infinite;
213
+ }
214
+ @keyframes spin { to { transform: rotate(360deg); } }
215
+ .footer { text-align: center; padding: 1.5rem; color: var(--text-muted); font-size: 0.75rem; border-top: 1px solid var(--border); margin-top: 2rem; }
216
+ </style>
217
+ </head>
218
+ <body>
219
+ <header class="header">
220
+ <div class="header-logo">
221
+ <svg viewBox="0 0 40 40" fill="none">
222
+ <rect x="4" y="4" width="32" height="32" rx="8" stroke="#3b82f6" stroke-width="2"/>
223
+ <path d="M20 10L28 16V28H12V16L20 10Z" fill="#3b82f6" fill-opacity="0.2" stroke="#3b82f6" stroke-width="1.5"/>
224
+ <circle cx="20" cy="21" r="3" fill="#3b82f6"/>
225
+ <path d="M17 28V24H23V28" stroke="#3b82f6" stroke-width="1.5"/>
226
+ </svg>
227
+ <h1>Digital <span>Fortress</span></h1>
228
+ </div>
229
+ <div class="header-status">
230
+ <div class="status-dot"></div>
231
+ <span id="headerStatus">Shield Active &mdash; All Systems Online</span>
232
+ </div>
233
+ </header>
234
+
235
+ <div class="container">
236
+ <div id="loadingState" class="loading"><div class="spinner"></div></div>
237
+
238
+ <div id="dashboardContent" style="display:none;">
239
+ <div class="stats-row">
240
+ <div class="stat-card blue">
241
+ <div class="stat-label">Protected Sites</div>
242
+ <div class="stat-value blue" id="sitesProtected">0</div>
243
+ <div class="stat-sub">Under fortress protection</div>
244
+ </div>
245
+ <div class="stat-card green">
246
+ <div class="stat-label">Trust Attestations</div>
247
+ <div class="stat-value green" id="totalAttestations">0</div>
248
+ <div class="stat-sub">From the agent network</div>
249
+ </div>
250
+ <div class="stat-card amber">
251
+ <div class="stat-label">Negotiation Deals</div>
252
+ <div class="stat-value amber" id="totalDeals">0</div>
253
+ <div class="stat-sub">With independent sites</div>
254
+ </div>
255
+ <div class="stat-card cyan">
256
+ <div class="stat-label">Total Savings</div>
257
+ <div class="stat-value cyan" id="totalSaved">$0</div>
258
+ <div class="stat-sub">Via direct negotiation</div>
259
+ </div>
260
+ <div class="stat-card red">
261
+ <div class="stat-label">Threats Blocked</div>
262
+ <div class="stat-value red" id="threatsBlocked">0</div>
263
+ <div class="stat-sub">Fraud &amp; hallucination attempts</div>
264
+ </div>
265
+ <div class="stat-card purple">
266
+ <div class="stat-label">Integrity Score</div>
267
+ <div class="stat-value purple" id="integrityScore">100%</div>
268
+ <div class="stat-sub">Cross-verification accuracy</div>
269
+ </div>
270
+ </div>
271
+
272
+ <div class="dashboard-grid">
273
+ <div class="panel">
274
+ <div class="panel-header">
275
+ <div class="panel-title">
276
+ <svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="M12 22s8-4 8-10V5l-8-3-8 3v7c0 6 8 10 8 10z"/></svg>
277
+ Fairness Radar
278
+ </div>
279
+ <div class="panel-badge" id="radarBadge">Live</div>
280
+ </div>
281
+ <div class="panel-body">
282
+ <div class="shield-radar">
283
+ <div class="radar-ring"></div>
284
+ <div class="radar-ring"></div>
285
+ <div class="radar-ring"></div>
286
+ <div class="radar-center safe" id="radarCenter">
287
+ <span id="radarScore">100</span>
288
+ <small>Safety Score</small>
289
+ </div>
290
+ <div id="radarDots"></div>
291
+ </div>
292
+ <div style="text-align:center;margin-top:1rem;">
293
+ <div style="font-size:0.8rem;color:var(--text-secondary);" id="radarSummary">
294
+ Agent checked 0 operations and found 0 trusted independent sites
295
+ </div>
296
+ </div>
297
+ </div>
298
+ </div>
299
+
300
+ <div class="panel">
301
+ <div class="panel-header">
302
+ <div class="panel-title">
303
+ <svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><rect x="3" y="11" width="18" height="11" rx="2" ry="2"/><path d="M7 11V7a5 5 0 0 1 10 0v4"/></svg>
304
+ Privacy Shield
305
+ </div>
306
+ </div>
307
+ <div class="panel-body">
308
+ <div class="privacy-meter">
309
+ <div class="privacy-row">
310
+ <div class="privacy-icon">&#x1F6E1;&#xFE0F;</div>
311
+ <div class="privacy-info">
312
+ <div class="privacy-label">Tracking Attempts Deflected</div>
313
+ <div class="privacy-desc">Decoy data sent to trackers</div>
314
+ </div>
315
+ <div class="privacy-count" id="trackingBlocked">0</div>
316
+ </div>
317
+ <div class="privacy-row">
318
+ <div class="privacy-icon">&#x1F512;</div>
319
+ <div class="privacy-info">
320
+ <div class="privacy-label">Intentions Encrypted</div>
321
+ <div class="privacy-desc">Searches and browsing encrypted</div>
322
+ </div>
323
+ <div class="privacy-count" id="intentionsEncrypted">0</div>
324
+ </div>
325
+ <div class="privacy-row">
326
+ <div class="privacy-icon">&#x2705;</div>
327
+ <div class="privacy-info">
328
+ <div class="privacy-label">Visual Verifications</div>
329
+ <div class="privacy-desc">DOM matched against screenshots</div>
330
+ </div>
331
+ <div class="privacy-count" id="visionChecks">0</div>
332
+ </div>
333
+ <div class="privacy-row">
334
+ <div class="privacy-icon">&#x26A0;&#xFE0F;</div>
335
+ <div class="privacy-info">
336
+ <div class="privacy-label">Hallucination Alerts</div>
337
+ <div class="privacy-desc">Discrepancies caught by anti-hallucination shield</div>
338
+ </div>
339
+ <div class="privacy-count" id="hallucinationAlerts">0</div>
340
+ </div>
341
+ </div>
342
+ </div>
343
+ </div>
344
+
345
+ <div class="panel">
346
+ <div class="panel-header">
347
+ <div class="panel-title">
348
+ <svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><polygon points="12 2 15.09 8.26 22 9.27 17 14.14 18.18 21.02 12 17.77 5.82 21.02 7 14.14 2 9.27 8.91 8.26 12 2"/></svg>
349
+ Site Reputation
350
+ </div>
351
+ <div class="panel-badge">Decentralized</div>
352
+ </div>
353
+ <div class="panel-body" id="reputationPanel">
354
+ <div class="empty-state"><p>No reputation data yet</p></div>
355
+ </div>
356
+ </div>
357
+
358
+ <div class="panel">
359
+ <div class="panel-header">
360
+ <div class="panel-title">
361
+ <svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="M12 1a3 3 0 0 0-3 3v8a3 3 0 0 0 6 0V4a3 3 0 0 0-3-3z"/><path d="M19 10v2a7 7 0 0 1-14 0v-2"/><line x1="12" y1="19" x2="12" y2="23"/></svg>
362
+ Negotiation Log
363
+ </div>
364
+ </div>
365
+ <div class="panel-body" id="negotiationPanel">
366
+ <div class="empty-state"><p>No negotiations yet</p></div>
367
+ </div>
368
+ </div>
369
+
370
+ <div class="panel full-width">
371
+ <div class="panel-header">
372
+ <div class="panel-title">
373
+ <svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="M1 12s4-8 11-8 11 8 11 8-4 8-11 8-11-8-11-8z"/><circle cx="12" cy="12" r="3"/></svg>
374
+ Cross-Verification Shield &mdash; Anti-Hallucination
375
+ </div>
376
+ <div class="panel-badge" id="shieldBadge">Active</div>
377
+ </div>
378
+ <div class="panel-body" id="verificationPanel">
379
+ <div class="rep-bar-container">
380
+ <div class="rep-bar-label"><span>Price Accuracy</span><span id="priceAccLabel">100%</span></div>
381
+ <div class="rep-bar-track"><div class="rep-bar-fill green" id="priceAccBar" style="width:100%"></div></div>
382
+ </div>
383
+ <div class="rep-bar-container">
384
+ <div class="rep-bar-label"><span>Text Match</span><span id="textMatchLabel">100%</span></div>
385
+ <div class="rep-bar-track"><div class="rep-bar-fill blue" id="textMatchBar" style="width:100%"></div></div>
386
+ </div>
387
+ <div class="rep-bar-container">
388
+ <div class="rep-bar-label"><span>Data Integrity</span><span id="dataIntegLabel">100%</span></div>
389
+ <div class="rep-bar-track"><div class="rep-bar-fill amber" id="dataIntegBar" style="width:100%"></div></div>
390
+ </div>
391
+ <ul class="check-list" id="checkList"></ul>
392
+ </div>
393
+ </div>
394
+
395
+ <div class="panel full-width">
396
+ <div class="panel-header">
397
+ <div class="panel-title">
398
+ <svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><circle cx="12" cy="12" r="10"/><line x1="2" y1="12" x2="22" y2="12"/><path d="M12 2a15.3 15.3 0 0 1 4 10 15.3 15.3 0 0 1-4 10 15.3 15.3 0 0 1-4-10 15.3 15.3 0 0 1 4-10z"/></svg>
399
+ Protected Sites
400
+ </div>
401
+ </div>
402
+ <div class="panel-body" style="padding:0;">
403
+ <table class="sites-table" id="sitesTable">
404
+ <thead>
405
+ <tr>
406
+ <th>Site</th>
407
+ <th>Reputation</th>
408
+ <th>Trust Level</th>
409
+ <th>Deals</th>
410
+ <th>Savings</th>
411
+ <th>Integrity</th>
412
+ </tr>
413
+ </thead>
414
+ <tbody id="sitesBody"></tbody>
415
+ </table>
416
+ </div>
417
+ </div>
418
+
419
+ <div class="panel full-width">
420
+ <div class="panel-header">
421
+ <div class="panel-title">
422
+ <svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><rect x="2" y="3" width="20" height="14" rx="2" ry="2"/><line x1="8" y1="21" x2="16" y2="21"/><line x1="12" y1="17" x2="12" y2="21"/></svg>
423
+ Sovereignty Button &mdash; Switch Agent Brain
424
+ </div>
425
+ </div>
426
+ <div class="panel-body">
427
+ <p style="font-size:0.85rem;color:var(--text-secondary);margin-bottom:1rem;">
428
+ Choose the AI engine powering your agent. The bridge (WAB) remains constant &mdash; swap the brain anytime:
429
+ </p>
430
+ <div class="model-switcher">
431
+ <button class="model-btn active" data-model="llama3">&#x1F999; Llama 3</button>
432
+ <button class="model-btn" data-model="gpt4">&#x1F916; GPT-4</button>
433
+ <button class="model-btn" data-model="claude">&#x1F9E0; Claude</button>
434
+ <button class="model-btn" data-model="gemini">&#x1F48E; Gemini</button>
435
+ <button class="model-btn" data-model="mistral">&#x1F30A; Mistral</button>
436
+ <button class="model-btn" data-model="ollama">&#x1F3E0; Ollama (Local)</button>
437
+ </div>
438
+ <p id="modelDesc" style="font-size:0.8rem;color:var(--text-muted);margin-top:0.75rem;">
439
+ Llama 3 &mdash; Open source, runs locally, your data never leaves your machine
440
+ </p>
441
+ </div>
442
+ </div>
443
+ </div>
444
+ </div>
445
+ </div>
446
+
447
+ <footer class="footer">
448
+ Web Agent Bridge v2.0.0 &mdash; Digital Fortress for Internet Sovereignty<br>
449
+ <span style="color:var(--accent-blue);">Digital fairness starts here</span>
450
+ </footer>
451
+
452
+ <script>
453
+ var API_BASE = '/api/sovereign';
454
+ var MODEL_DESCRIPTIONS = {
455
+ llama3: 'Llama 3 \u2014 Open source, runs locally, your data never leaves your machine',
456
+ gpt4: 'GPT-4 \u2014 Most powerful model, requires OpenAI API key',
457
+ claude: 'Claude \u2014 Excels at deep analysis and complex tasks',
458
+ gemini: 'Gemini \u2014 Google multimodal model (text + image)',
459
+ mistral: 'Mistral \u2014 European open-source model, fast and lightweight',
460
+ ollama: 'Ollama \u2014 100% local execution, full privacy, no internet required'
461
+ };
462
+
463
+ function getToken() {
464
+ return localStorage.getItem('wab_token') || '';
465
+ }
466
+
467
+ async function fetchDashboard() {
468
+ var token = getToken();
469
+ if (!token) {
470
+ document.getElementById('loadingState').innerHTML =
471
+ '<div class="empty-state"><p>Please <a href="/login" style="color:var(--accent-blue)">sign in</a> to view the Sovereign Dashboard</p></div>';
472
+ return;
473
+ }
474
+
475
+ try {
476
+ var res = await fetch(API_BASE + '/dashboard/sovereign', {
477
+ headers: { 'Authorization': 'Bearer ' + token }
478
+ });
479
+
480
+ if (!res.ok) {
481
+ if (res.status === 401) {
482
+ document.getElementById('loadingState').innerHTML =
483
+ '<div class="empty-state"><p>Session expired. Please <a href="/login" style="color:var(--accent-blue)">sign in</a> again</p></div>';
484
+ return;
485
+ }
486
+ throw new Error('API error');
487
+ }
488
+
489
+ var data = await res.json();
490
+ renderDashboard(data);
491
+ } catch (err) {
492
+ renderDashboard(getDemoData());
493
+ }
494
+ }
495
+
496
+ function getDemoData() {
497
+ return {
498
+ overview: { sitesProtected: 3, shieldStatus: 'active' },
499
+ reputation: { totalAttestations: 47, avgReputationScore: 82 },
500
+ negotiation: { totalDeals: 12, totalSaved: 234.50 },
501
+ shield: { totalChecks: 156, threatsBlocked: 5, integrityScore: 97 },
502
+ privacy: { trackingAttempts: 23, intentionsEncrypted: 89, dataShielded: 100 },
503
+ sites: [
504
+ { siteId: 'demo-1', domain: 'honey-farm.local', reputationScore: 92, trustLevel: 'exemplary', dealsMade: 5, avgSavings: 12.5, integrityRating: 100 },
505
+ { siteId: 'demo-2', domain: 'olive-oil.store', reputationScore: 78, trustLevel: 'trusted', dealsMade: 4, avgSavings: 8.2, integrityRating: 95 },
506
+ { siteId: 'demo-3', domain: 'local-hotel.com', reputationScore: 65, trustLevel: 'emerging', dealsMade: 3, avgSavings: 15.0, integrityRating: 98 }
507
+ ]
508
+ };
509
+ }
510
+
511
+ function renderDashboard(data) {
512
+ document.getElementById('loadingState').style.display = 'none';
513
+ document.getElementById('dashboardContent').style.display = 'block';
514
+
515
+ animateNumber('sitesProtected', data.overview.sitesProtected);
516
+ animateNumber('totalAttestations', data.reputation.totalAttestations);
517
+ animateNumber('totalDeals', data.negotiation.totalDeals);
518
+ document.getElementById('totalSaved').textContent = '$' + (data.negotiation.totalSaved || 0).toFixed(2);
519
+ animateNumber('threatsBlocked', data.shield.threatsBlocked);
520
+ document.getElementById('integrityScore').textContent = (data.shield.integrityScore || 100) + '%';
521
+
522
+ var score = data.shield.integrityScore || 100;
523
+ var radarCenter = document.getElementById('radarCenter');
524
+ document.getElementById('radarScore').textContent = score;
525
+ radarCenter.className = 'radar-center ' + (score >= 80 ? 'safe' : score >= 50 ? 'warn' : 'danger');
526
+
527
+ document.getElementById('radarDots').innerHTML = generateRadarDots(data.shield.threatsBlocked, data.shield.totalChecks);
528
+
529
+ var independentCount = (data.sites || []).filter(function(s) { return s.reputationScore >= 60; }).length;
530
+ document.getElementById('radarSummary').textContent =
531
+ 'Agent checked ' + data.shield.totalChecks + ' operations and found ' + independentCount + ' trusted independent sites';
532
+
533
+ document.getElementById('trackingBlocked').textContent = data.privacy ? data.privacy.trackingAttempts : data.shield.threatsBlocked || 0;
534
+ document.getElementById('intentionsEncrypted').textContent = data.privacy ? data.privacy.intentionsEncrypted : data.shield.totalChecks || 0;
535
+ document.getElementById('visionChecks').textContent = data.shield.totalChecks || 0;
536
+ document.getElementById('hallucinationAlerts').textContent = data.shield.threatsBlocked || 0;
537
+
538
+ renderReputationPanel(data.sites || []);
539
+ renderNegotiationPanel(data.sites || [], data.negotiation);
540
+
541
+ var integ = data.shield.integrityScore || 100;
542
+ setBar('priceAccBar', 'priceAccLabel', integ);
543
+ setBar('textMatchBar', 'textMatchLabel', Math.min(integ + 2, 100));
544
+ setBar('dataIntegBar', 'dataIntegLabel', Math.min(integ + 1, 100));
545
+
546
+ renderCheckList(data.shield);
547
+ renderSitesTable(data.sites || []);
548
+ }
549
+
550
+ function animateNumber(id, target) {
551
+ var el = document.getElementById(id);
552
+ var current = 0;
553
+ var step = Math.max(1, Math.floor(target / 30));
554
+ var interval = setInterval(function() {
555
+ current += step;
556
+ if (current >= target) { current = target; clearInterval(interval); }
557
+ el.textContent = current;
558
+ }, 30);
559
+ }
560
+
561
+ function setBar(barId, labelId, value) {
562
+ document.getElementById(barId).style.width = value + '%';
563
+ document.getElementById(labelId).textContent = value + '%';
564
+ }
565
+
566
+ function generateRadarDots(threats, total) {
567
+ var html = '';
568
+ var positions = [
569
+ { top: '20%', left: '25%' }, { top: '35%', left: '70%' },
570
+ { top: '60%', left: '15%' }, { top: '75%', left: '60%' },
571
+ { top: '40%', left: '40%' }, { top: '55%', left: '80%' },
572
+ { top: '25%', left: '55%' }, { top: '70%', left: '35%' }
573
+ ];
574
+ var count = Math.min(8, (total || 0));
575
+ for (var i = 0; i < count; i++) {
576
+ var pos = positions[i % positions.length];
577
+ var cls = i < (threats || 0) ? 'red' : (i < count * 0.3 ? 'amber' : 'green');
578
+ html += '<div class="radar-dot ' + cls + '" style="top:' + pos.top + ';left:' + pos.left + '"></div>';
579
+ }
580
+ return html;
581
+ }
582
+
583
+ function renderReputationPanel(sites) {
584
+ var panel = document.getElementById('reputationPanel');
585
+ if (!sites.length) return;
586
+ var html = '';
587
+ for (var i = 0; i < sites.length; i++) {
588
+ var site = sites[i];
589
+ var cls = site.reputationScore >= 80 ? 'green' : site.reputationScore >= 50 ? 'blue' : 'amber';
590
+ html += '<div class="rep-bar-container">' +
591
+ '<div class="rep-bar-label"><span>' + site.domain + '</span><span>' + site.reputationScore + '/100</span></div>' +
592
+ '<div class="rep-bar-track"><div class="rep-bar-fill ' + cls + '" style="width:' + site.reputationScore + '%"></div></div></div>';
593
+ }
594
+ panel.innerHTML = html;
595
+ }
596
+
597
+ function renderNegotiationPanel(sites, neg) {
598
+ var panel = document.getElementById('negotiationPanel');
599
+ if (!neg.totalDeals) return;
600
+ var html = '<ul class="neg-timeline">';
601
+ for (var i = 0; i < sites.length; i++) {
602
+ var site = sites[i];
603
+ if (site.dealsMade > 0) {
604
+ html += '<li class="neg-item"><div class="neg-icon deal">&#x1F4B0;</div><div class="neg-details">' +
605
+ '<div class="neg-title">' + site.domain + '</div>' +
606
+ '<div class="neg-meta">' + site.dealsMade + ' deals &mdash; avg savings <span class="neg-savings">' + site.avgSavings + '%</span></div></div></li>';
607
+ }
608
+ }
609
+ html += '</ul>';
610
+ panel.innerHTML = html;
611
+ }
612
+
613
+ function renderCheckList(shield) {
614
+ var list = document.getElementById('checkList');
615
+ var checks = [
616
+ { name: 'DOM vs Vision Match', status: shield.integrityScore >= 90 ? 'pass' : 'warn' },
617
+ { name: 'Price Sanity Verification', status: shield.threatsBlocked === 0 ? 'pass' : 'warn' },
618
+ { name: 'Deception Attempt Detection', status: shield.threatsBlocked > 3 ? 'fail' : 'pass' },
619
+ { name: 'Temporal Consistency (Price History)', status: 'pass' },
620
+ { name: 'Cryptographic Attestation Signatures', status: 'pass' }
621
+ ];
622
+ list.innerHTML = checks.map(function(c) {
623
+ return '<li class="check-item"><span class="check-badge ' + c.status + '">' +
624
+ (c.status === 'pass' ? '&#x2713;' : c.status === 'warn' ? '!' : '&#x2717;') +
625
+ '</span>' + c.name + '</li>';
626
+ }).join('');
627
+ }
628
+
629
+ function renderSitesTable(sites) {
630
+ var tbody = document.getElementById('sitesBody');
631
+ if (!sites.length) {
632
+ tbody.innerHTML = '<tr><td colspan="6" style="text-align:center;color:var(--text-muted);padding:2rem;">No registered sites</td></tr>';
633
+ return;
634
+ }
635
+ tbody.innerHTML = sites.map(function(s) {
636
+ var color = s.reputationScore >= 80 ? 'var(--accent-green)' : s.reputationScore >= 50 ? 'var(--accent-blue)' : 'var(--accent-amber)';
637
+ return '<tr><td style="font-weight:500">' + s.domain + '</td>' +
638
+ '<td><span style="color:' + color + ';font-weight:600">' + s.reputationScore + '</span></td>' +
639
+ '<td><span class="trust-badge ' + s.trustLevel + '">' + capitalize(s.trustLevel) + '</span></td>' +
640
+ '<td>' + (s.dealsMade || 0) + '</td>' +
641
+ '<td style="color:var(--accent-green);font-weight:500">' + (s.avgSavings ? s.avgSavings + '%' : '&mdash;') + '</td>' +
642
+ '<td>' + (s.integrityRating || 100) + '%</td></tr>';
643
+ }).join('');
644
+ }
645
+
646
+ function capitalize(str) { return str ? str.charAt(0).toUpperCase() + str.slice(1) : ''; }
647
+
648
+ document.querySelectorAll('.model-btn').forEach(function(btn) {
649
+ btn.addEventListener('click', function() {
650
+ document.querySelectorAll('.model-btn').forEach(function(b) { b.classList.remove('active'); });
651
+ btn.classList.add('active');
652
+ document.getElementById('modelDesc').textContent = MODEL_DESCRIPTIONS[btn.dataset.model];
653
+ });
654
+ });
655
+
656
+ fetchDashboard();
657
+ setInterval(fetchDashboard, 30000);
658
+ </script>
659
+ </body>
660
+ </html>
package/sdk/package.json CHANGED
@@ -1,5 +1,5 @@
1
1
  {
2
- "name": "@anthropic-wab/agent-sdk",
2
+ "name": "web-agent-bridge-sdk",
3
3
  "version": "2.0.0",
4
4
  "description": "SDK for building AI agents that interact with Web Agent Bridge (WAB)",
5
5
  "main": "index.js",