web-agent-bridge 3.2.0 → 3.3.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 (202) hide show
  1. package/LICENSE +72 -72
  2. package/README.ar.md +1286 -1152
  3. package/README.md +1764 -1635
  4. package/bin/agent-runner.js +474 -474
  5. package/bin/cli.js +237 -138
  6. package/bin/wab.js +80 -80
  7. package/examples/bidi-agent.js +119 -119
  8. package/examples/cross-site-agent.js +91 -91
  9. package/examples/mcp-agent.js +94 -94
  10. package/examples/next-app-router/README.md +44 -44
  11. package/examples/puppeteer-agent.js +108 -108
  12. package/examples/saas-dashboard/README.md +55 -55
  13. package/examples/shopify-hydrogen/README.md +74 -74
  14. package/examples/vision-agent.js +171 -171
  15. package/examples/wordpress-elementor/README.md +77 -77
  16. package/package.json +16 -3
  17. package/public/.well-known/agent-tools.json +180 -180
  18. package/public/.well-known/ai-assets.json +59 -59
  19. package/public/.well-known/security.txt +8 -0
  20. package/public/agent-workspace.html +349 -349
  21. package/public/ai.html +198 -198
  22. package/public/api.html +413 -412
  23. package/public/browser.html +486 -486
  24. package/public/commander-dashboard.html +243 -243
  25. package/public/cookies.html +210 -210
  26. package/public/css/agent-workspace.css +1713 -1713
  27. package/public/css/premium.css +317 -317
  28. package/public/css/styles.css +1235 -1235
  29. package/public/dashboard.html +706 -706
  30. package/public/dns.html +507 -0
  31. package/public/docs.html +587 -587
  32. package/public/feed.xml +89 -89
  33. package/public/growth.html +463 -463
  34. package/public/index.html +1070 -982
  35. package/public/integrations.html +556 -0
  36. package/public/js/agent-workspace.js +1740 -1740
  37. package/public/js/auth-nav.js +31 -31
  38. package/public/js/auth-redirect.js +12 -12
  39. package/public/js/cookie-consent.js +56 -56
  40. package/public/js/wab-demo-page.js +721 -721
  41. package/public/js/ws-client.js +74 -74
  42. package/public/llms-full.txt +360 -360
  43. package/public/llms.txt +125 -125
  44. package/public/login.html +85 -85
  45. package/public/mesh-dashboard.html +328 -328
  46. package/public/openapi.json +580 -580
  47. package/public/phone-shield.html +281 -0
  48. package/public/premium-dashboard.html +2489 -2489
  49. package/public/premium.html +793 -793
  50. package/public/privacy.html +297 -297
  51. package/public/register.html +105 -105
  52. package/public/robots.txt +87 -87
  53. package/public/script/wab-consent.d.ts +36 -36
  54. package/public/script/wab-consent.js +104 -104
  55. package/public/script/wab-schema.js +131 -131
  56. package/public/script/wab.d.ts +108 -108
  57. package/public/script/wab.min.js +580 -580
  58. package/public/security.txt +8 -0
  59. package/public/terms.html +256 -256
  60. package/script/ai-agent-bridge.js +1754 -1754
  61. package/sdk/README.md +99 -99
  62. package/sdk/agent-mesh.js +449 -449
  63. package/sdk/commander.js +262 -262
  64. package/sdk/index.d.ts +464 -464
  65. package/sdk/index.js +12 -1
  66. package/sdk/multi-agent.js +318 -318
  67. package/sdk/package.json +1 -1
  68. package/sdk/safety-shield.js +219 -0
  69. package/sdk/schema-discovery.js +83 -83
  70. package/server/adapters/index.js +520 -520
  71. package/server/config/plans.js +367 -367
  72. package/server/config/secrets.js +102 -102
  73. package/server/control-plane/index.js +301 -301
  74. package/server/data-plane/index.js +354 -354
  75. package/server/index.js +531 -427
  76. package/server/llm/index.js +404 -404
  77. package/server/middleware/adminAuth.js +35 -35
  78. package/server/middleware/auth.js +50 -50
  79. package/server/middleware/featureGate.js +88 -88
  80. package/server/middleware/rateLimits.js +100 -100
  81. package/server/middleware/sensitiveAction.js +157 -0
  82. package/server/migrations/001_add_analytics_indexes.sql +7 -7
  83. package/server/migrations/002_premium_features.sql +418 -418
  84. package/server/migrations/003_ads_integer_cents.sql +33 -33
  85. package/server/migrations/004_agent_os.sql +158 -158
  86. package/server/migrations/005_marketplace_metering.sql +126 -126
  87. package/server/models/adapters/index.js +33 -33
  88. package/server/models/adapters/mysql.js +183 -183
  89. package/server/models/adapters/postgresql.js +172 -172
  90. package/server/models/adapters/sqlite.js +7 -7
  91. package/server/models/db.js +681 -681
  92. package/server/observability/failure-analysis.js +337 -337
  93. package/server/observability/index.js +394 -394
  94. package/server/protocol/capabilities.js +223 -223
  95. package/server/protocol/index.js +243 -243
  96. package/server/protocol/schema.js +584 -584
  97. package/server/registry/certification.js +271 -271
  98. package/server/registry/index.js +326 -326
  99. package/server/routes/admin-premium.js +671 -671
  100. package/server/routes/admin.js +261 -261
  101. package/server/routes/ads.js +130 -130
  102. package/server/routes/agent-workspace.js +540 -540
  103. package/server/routes/api.js +150 -150
  104. package/server/routes/auth.js +71 -71
  105. package/server/routes/billing.js +45 -45
  106. package/server/routes/commander.js +316 -316
  107. package/server/routes/demo-showcase.js +332 -332
  108. package/server/routes/demo-store.js +154 -0
  109. package/server/routes/discovery.js +417 -417
  110. package/server/routes/gateway.js +173 -157
  111. package/server/routes/license.js +251 -240
  112. package/server/routes/mesh.js +469 -469
  113. package/server/routes/noscript.js +543 -543
  114. package/server/routes/premium-v2.js +686 -686
  115. package/server/routes/premium.js +724 -724
  116. package/server/routes/runtime.js +2148 -2147
  117. package/server/routes/sovereign.js +465 -385
  118. package/server/routes/universal.js +200 -185
  119. package/server/routes/wab-api.js +850 -501
  120. package/server/runtime/container-worker.js +111 -111
  121. package/server/runtime/container.js +448 -448
  122. package/server/runtime/distributed-worker.js +362 -362
  123. package/server/runtime/event-bus.js +210 -210
  124. package/server/runtime/index.js +253 -253
  125. package/server/runtime/queue.js +599 -599
  126. package/server/runtime/replay.js +666 -666
  127. package/server/runtime/sandbox.js +266 -266
  128. package/server/runtime/scheduler.js +534 -534
  129. package/server/runtime/session-engine.js +293 -293
  130. package/server/runtime/state-manager.js +188 -188
  131. package/server/security/cross-site-redactor.js +196 -0
  132. package/server/security/dry-run.js +180 -0
  133. package/server/security/human-gate-rate-limit.js +147 -0
  134. package/server/security/human-gate-transports.js +178 -0
  135. package/server/security/human-gate.js +281 -0
  136. package/server/security/index.js +368 -368
  137. package/server/security/intent-engine.js +245 -0
  138. package/server/security/reward-guard.js +171 -0
  139. package/server/security/rollback-store.js +239 -0
  140. package/server/security/token-scope.js +404 -0
  141. package/server/security/url-policy.js +139 -0
  142. package/server/services/agent-chat.js +506 -506
  143. package/server/services/agent-learning.js +601 -575
  144. package/server/services/agent-memory.js +625 -625
  145. package/server/services/agent-mesh.js +555 -539
  146. package/server/services/agent-symphony.js +717 -717
  147. package/server/services/agent-tasks.js +1807 -1807
  148. package/server/services/api-key-engine.js +292 -261
  149. package/server/services/cluster.js +894 -894
  150. package/server/services/commander.js +738 -738
  151. package/server/services/edge-compute.js +440 -440
  152. package/server/services/email.js +204 -204
  153. package/server/services/hosted-runtime.js +205 -205
  154. package/server/services/lfd.js +635 -635
  155. package/server/services/local-ai.js +389 -389
  156. package/server/services/marketplace.js +270 -270
  157. package/server/services/metering.js +182 -182
  158. package/server/services/modules/affiliate-intelligence.js +93 -93
  159. package/server/services/modules/agent-firewall.js +90 -90
  160. package/server/services/modules/bounty.js +89 -89
  161. package/server/services/modules/collective-bargaining.js +92 -92
  162. package/server/services/modules/dark-pattern.js +66 -66
  163. package/server/services/modules/gov-intelligence.js +45 -45
  164. package/server/services/modules/neural.js +55 -55
  165. package/server/services/modules/notary.js +49 -49
  166. package/server/services/modules/price-time-machine.js +86 -86
  167. package/server/services/modules/protocol.js +104 -104
  168. package/server/services/negotiation.js +439 -439
  169. package/server/services/plugins.js +771 -771
  170. package/server/services/price-intelligence.js +566 -566
  171. package/server/services/price-shield.js +1137 -1137
  172. package/server/services/reputation.js +465 -465
  173. package/server/services/search-engine.js +357 -357
  174. package/server/services/security.js +513 -513
  175. package/server/services/self-healing.js +843 -843
  176. package/server/services/sovereign-shield.js +542 -0
  177. package/server/services/stripe.js +192 -192
  178. package/server/services/swarm.js +788 -788
  179. package/server/services/universal-scraper.js +662 -661
  180. package/server/services/verification.js +481 -481
  181. package/server/services/vision.js +1163 -1163
  182. package/server/utils/cache.js +125 -125
  183. package/server/utils/migrate.js +81 -81
  184. package/server/utils/safe-fetch.js +228 -0
  185. package/server/utils/secureFields.js +50 -50
  186. package/server/ws.js +161 -161
  187. package/templates/artisan-marketplace.yaml +104 -104
  188. package/templates/book-price-scout.yaml +98 -98
  189. package/templates/electronics-price-tracker.yaml +108 -108
  190. package/templates/flight-deal-hunter.yaml +113 -113
  191. package/templates/freelancer-direct.yaml +116 -116
  192. package/templates/grocery-price-compare.yaml +93 -93
  193. package/templates/hotel-direct-booking.yaml +113 -113
  194. package/templates/local-services.yaml +98 -98
  195. package/templates/olive-oil-tunisia.yaml +88 -88
  196. package/templates/organic-farm-fresh.yaml +101 -101
  197. package/templates/restaurant-direct.yaml +97 -97
  198. package/public/score.html +0 -263
  199. package/server/migrations/006_growth_suite.sql +0 -138
  200. package/server/routes/growth.js +0 -962
  201. package/server/services/fairness-engine.js +0 -409
  202. package/server/services/fairness.js +0 -420
@@ -0,0 +1,507 @@
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>WAB DNS Discovery — Setup & Live Verifier</title>
7
+ <meta name="description" content="Complete guide to WAB DNS Discovery: TXT record format, step-by-step setup for Cloudflare, cPanel, GoDaddy, Namecheap, Route 53, and a live DoH-based verifier.">
8
+ <link rel="preconnect" href="https://fonts.googleapis.com">
9
+ <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
10
+ <link rel="preload" href="https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700;800&family=JetBrains+Mono:wght@400;500&display=swap" as="style" onload="this.onload=null;this.rel='stylesheet'">
11
+ <noscript><link href="https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700;800&family=JetBrains+Mono:wght@400;500&display=swap" rel="stylesheet"></noscript>
12
+ <link rel="stylesheet" href="/css/styles.css?v=3.2.0">
13
+ <style>
14
+ body{background:#070d19;color:#e5edff}
15
+ .hero{padding:110px 24px 32px;text-align:center}
16
+ .hero h1{font-size:clamp(2rem,4vw,3rem);margin-bottom:10px}
17
+ .hero p{max-width:880px;margin:0 auto;color:#99a8c7;line-height:1.7}
18
+ .lang{display:flex;gap:10px;justify-content:center;margin:0 0 22px}
19
+ .lang button{border:1px solid rgba(255,255,255,.15);background:rgba(255,255,255,.04);color:#e5edff;padding:8px 14px;border-radius:10px;cursor:pointer}
20
+ .lang button.active{background:linear-gradient(135deg,#f59e0b,#b45309);border-color:transparent}
21
+ .wrap{max-width:1100px;margin:0 auto;padding:0 22px 60px}
22
+ .grid{display:grid;grid-template-columns:repeat(auto-fit,minmax(320px,1fr));gap:18px;margin:18px 0}
23
+ .card{background:linear-gradient(180deg,rgba(17,24,39,.92),rgba(12,18,31,.96));border:1px solid rgba(148,163,184,.18);border-radius:16px;padding:18px}
24
+ .card h3{margin:0 0 8px;font-size:1.07rem;color:#fcd34d}
25
+ .card h4{margin:14px 0 6px;color:#fde68a;font-size:.98rem}
26
+ .card p,.card li{color:#bcc7e0;line-height:1.7;font-size:.94rem}
27
+ .card ol,.card ul{margin:6px 0 8px 22px}
28
+ .badge{display:inline-block;background:rgba(245,158,11,.14);border:1px solid rgba(245,158,11,.4);color:#fbbf24;padding:4px 9px;border-radius:999px;font-size:.73rem;font-weight:700;margin:6px 0}
29
+ code,pre{font-family:'JetBrains Mono',monospace}
30
+ code{background:rgba(2,6,23,.7);border:1px solid rgba(148,163,184,.2);padding:2px 6px;border-radius:6px;font-size:.85rem;color:#fcd34d}
31
+ pre{background:#020617;border:1px solid rgba(148,163,184,.25);padding:12px;border-radius:10px;font-size:.82rem;color:#a5b4fc;overflow:auto;line-height:1.55}
32
+ table{width:100%;border-collapse:collapse;margin:8px 0}
33
+ th,td{border:1px solid rgba(148,163,184,.18);padding:8px 10px;text-align:left;font-size:.9rem;color:#dbe4f5}
34
+ th{background:rgba(245,158,11,.1);color:#fcd34d}
35
+ .verifier{background:rgba(2,6,23,.7);border:1px solid rgba(245,158,11,.3);border-radius:14px;padding:16px;margin-top:12px}
36
+ .verifier label{display:block;font-size:.78rem;color:#9fb0ce;margin-bottom:4px}
37
+ .verifier input,.verifier select{width:100%;background:#0a1324;border:1px solid rgba(148,163,184,.27);border-radius:10px;color:#e2e8f0;padding:10px;font-family:Inter,sans-serif}
38
+ .row{display:grid;grid-template-columns:2fr 1fr;gap:10px}
39
+ @media (max-width:640px){.row{grid-template-columns:1fr}}
40
+ .btn{margin-top:10px;background:linear-gradient(135deg,#f59e0b,#b45309);color:#fff;border:none;padding:10px 14px;border-radius:10px;cursor:pointer;font-weight:700}
41
+ .btn.secondary{background:linear-gradient(135deg,#334155,#1e293b)}
42
+ .ok{color:#4ade80}.warn{color:#facc15}.danger{color:#f87171}
43
+ .toc{display:flex;flex-wrap:wrap;gap:8px;justify-content:center;margin:0 0 14px}
44
+ .toc a{background:rgba(255,255,255,.04);border:1px solid rgba(148,163,184,.22);color:#e5edff;padding:6px 12px;border-radius:999px;font-size:.85rem;text-decoration:none}
45
+ .toc a:hover{border-color:#fbbf24;color:#fcd34d}
46
+ </style>
47
+ </head>
48
+ <body>
49
+ <nav class="navbar" id="navbar">
50
+ <div class="container">
51
+ <a href="/" class="navbar-brand"><div class="brand-icon">⚡</div><span>WAB</span></a>
52
+ <ul class="navbar-links">
53
+ <li><a href="/">Home</a></li>
54
+ <li><a href="/integrations">Integrations</a></li>
55
+ <li><a href="/dns" class="active">DNS Discovery</a></li>
56
+ <li><a href="/phone-shield">Phone Shield</a></li>
57
+ <li><a href="/sovereign">Sovereign</a></li>
58
+ <li><a href="/docs">Docs</a></li>
59
+ </ul>
60
+ </div>
61
+ </nav>
62
+
63
+ <section class="hero">
64
+ <div class="lang">
65
+ <button id="enBtn" class="active" onclick="setLang('en')">English</button>
66
+ <button id="arBtn" onclick="setLang('ar')">العربية</button>
67
+ </div>
68
+ <h1 data-en="WAB DNS Discovery" data-ar="اكتشاف WAB عبر DNS">WAB DNS Discovery</h1>
69
+ <p data-en="Announce your AI-readiness at the infrastructure level. Add a single DNS TXT record at _wab.yourdomain.com and any compatible AI agent will instantly find your wab.json capabilities — no HTTP probe required." data-ar="أعلن عن جاهزية موقعك للذكاء الاصطناعي على مستوى البنية التحتية. أضف سجل TXT واحد في _wab.yourdomain.com وسيجد أي وكيل ذكاء اصطناعي متوافق ملف القدرات wab.json فوراً — دون الحاجة لأي طلب HTTP أولي.">Announce your AI-readiness at the infrastructure level. Add a single DNS TXT record at <code>_wab.yourdomain.com</code> and any compatible AI agent will instantly find your <code>wab.json</code> capabilities — no HTTP probe required.</p>
70
+ <div class="toc">
71
+ <a href="#what-is">What & Why</a>
72
+ <a href="#format">Record Format</a>
73
+ <a href="#verifier">Live Verifier</a>
74
+ <a href="#setup">Setup Guides</a>
75
+ <a href="#troubleshoot">Troubleshooting</a>
76
+ <a href="#repo-links">Repo & Docs</a>
77
+ </div>
78
+ </section>
79
+
80
+ <div class="wrap">
81
+
82
+ <!-- ═══════════════ WHAT & WHY ═══════════════ -->
83
+ <div class="card" id="what-is">
84
+ <h3 data-en="What is WAB DNS Discovery?" data-ar="ما هو اكتشاف WAB عبر DNS؟">What is WAB DNS Discovery?</h3>
85
+ <p data-en="WAB DNS Discovery is a lightweight protocol that lets AI agents instantly know whether a domain supports WAB and where to fetch its capabilities document. It works exactly like SPF, DKIM, or DMARC for email — a single TXT record at a well-known subdomain advertises your protocol support." data-ar="اكتشاف WAB عبر DNS هو بروتوكول خفيف يسمح لوكلاء الذكاء الاصطناعي بمعرفة فورية ما إذا كان النطاق يدعم WAB وأين يجد ملف القدرات الخاص به. يعمل تماماً مثل SPF و DKIM و DMARC للبريد الإلكتروني — سجل TXT واحد في نطاق فرعي معروف يعلن دعم البروتوكول.">WAB DNS Discovery is a lightweight protocol that lets AI agents instantly know whether a domain supports WAB and where to fetch its capabilities document. It works exactly like SPF, DKIM, or DMARC for email — a single TXT record at a well-known subdomain advertises your protocol support.</p>
86
+ <h4 data-en="Why use it?" data-ar="لماذا تستخدمها؟">Why use it?</h4>
87
+ <ul>
88
+ <li data-en="Zero HTTP probing — agents resolve DNS once and skip the trial-and-error of fetching /.well-known/wab.json blindly." data-ar="بدون أي طلب HTTP استكشافي — يقوم الوكيل بحل DNS مرة واحدة بدلاً من محاولة جلب /.well-known/wab.json بشكل أعمى.">Zero HTTP probing — agents resolve DNS once and skip the trial-and-error of fetching <code>/.well-known/wab.json</code> blindly.</li>
89
+ <li data-en="Infrastructure-first onboarding — works even before your site has any code change. Pure DNS." data-ar="إعداد عبر البنية التحتية — يعمل قبل أي تعديل برمجي على موقعك. DNS فقط.">Infrastructure-first onboarding — works even before your site has any code change. Pure DNS.</li>
90
+ <li data-en="Cacheable, fast, and globally propagated by every recursive resolver in the world." data-ar="قابل للتخزين المؤقت، سريع، ومنتشر عالمياً عبر كل خوادم DNS التكرارية.">Cacheable, fast, and globally propagated by every recursive resolver in the world.</li>
91
+ <li data-en="Versionable — the v=wab1 prefix lets the protocol evolve without breaking older agents." data-ar="قابل للترقية — البادئة v=wab1 تسمح بتطوير البروتوكول دون كسر الوكلاء القدامى.">Versionable — the <code>v=wab1</code> prefix lets the protocol evolve without breaking older agents.</li>
92
+ </ul>
93
+ <span class="badge" data-en="MIT-licensed open protocol" data-ar="بروتوكول مفتوح برخصة MIT">MIT-licensed open protocol</span>
94
+ </div>
95
+
96
+ <!-- ═══════════════ HOW IT WORKS ═══════════════ -->
97
+ <div class="card">
98
+ <h3 data-en="How it works (under the hood)" data-ar="كيف يعمل (الآلية الداخلية)">How it works (under the hood)</h3>
99
+ <ol>
100
+ <li data-en="The AI agent resolves a TXT query on _wab.example.com." data-ar="يقوم الوكيل بحل استعلام TXT على _wab.example.com.">The AI agent resolves a TXT query on <code>_wab.example.com</code>.</li>
101
+ <li data-en="Your authoritative DNS returns: v=wab1; endpoint=https://example.com/.well-known/wab.json" data-ar="يعيد DNS الموثوق: v=wab1; endpoint=https://example.com/.well-known/wab.json">Your authoritative DNS returns: <code>v=wab1; endpoint=https://example.com/.well-known/wab.json</code></li>
102
+ <li data-en="The agent parses the v= and endpoint= parameters, validates the version, then fetches the capabilities document directly." data-ar="يحلل الوكيل المعاملات v= و endpoint=، يتحقق من الإصدار، ثم يجلب ملف القدرات مباشرة.">The agent parses the <code>v=</code> and <code>endpoint=</code> parameters, validates the version, then fetches the capabilities document directly.</li>
103
+ <li data-en="Optional fields can be added later: feat=, sig=, ttl=, etc." data-ar="حقول اختيارية يمكن إضافتها لاحقاً: feat=, sig=, ttl=, إلخ.">Optional fields can be added later: <code>feat=</code>, <code>sig=</code>, <code>ttl=</code>, etc.</li>
104
+ </ol>
105
+ </div>
106
+
107
+ <!-- ═══════════════ FORMAT ═══════════════ -->
108
+ <div class="card" id="format">
109
+ <h3 data-en="The TXT Record Format" data-ar="صيغة سجل TXT">The TXT Record Format</h3>
110
+ <table>
111
+ <tr><th data-en="Field" data-ar="الحقل">Field</th><th data-en="Value" data-ar="القيمة">Value</th><th data-en="Description" data-ar="الوصف">Description</th></tr>
112
+ <tr><td>Type</td><td><code>TXT</code></td><td data-en="Plain text record" data-ar="سجل نصي">Plain text record</td></tr>
113
+ <tr><td>Name / Host</td><td><code>_wab</code></td><td data-en="Subdomain prefix → _wab.yourdomain.com" data-ar="بادئة نطاق فرعي → _wab.yourdomain.com">Subdomain prefix → <code>_wab.yourdomain.com</code></td></tr>
114
+ <tr><td>Value</td><td><code>v=wab1; endpoint=https://yourdomain.com/.well-known/wab.json</code></td><td data-en="Protocol version + capabilities URL" data-ar="إصدار البروتوكول + رابط ملف القدرات">Protocol version + capabilities URL</td></tr>
115
+ <tr><td>TTL</td><td><code>3600</code> / Auto</td><td data-en="Standard cache lifetime" data-ar="مدة التخزين الافتراضية">Standard cache lifetime</td></tr>
116
+ </table>
117
+ <pre>_wab.yourdomain.com. 3600 IN TXT "v=wab1; endpoint=https://yourdomain.com/.well-known/wab.json"</pre>
118
+ </div>
119
+
120
+ <!-- ═══════════════ RECORDS FOR webagentbridge.com ═══════════════ -->
121
+ <div class="card" id="records">
122
+ <h3 data-en="DNS Records for webagentbridge.com (canonical)" data-ar="سجلات DNS لـ webagentbridge.com (المرجعية)">DNS Records for webagentbridge.com (canonical)</h3>
123
+ <p data-en="The exact records the WAB site itself publishes. Each row is verified live against Cloudflare DoH (1.1.1.1) when this page loads. Add the equivalents under your own domain to advertise WAB protocol support, agent endpoints, and trust." data-ar="السجلات التي يستخدمها موقع WAB نفسه. يتم التحقق من كل سطر مباشرة عبر Cloudflare DoH عند تحميل هذه الصفحة. أضف ما يعادلها تحت نطاقك للإعلان عن دعم بروتوكول WAB ونقاط النهاية والثقة.">The exact records the WAB site itself publishes. Each row is verified live against Cloudflare DoH (1.1.1.1) when this page loads.</p>
124
+ <div id="recordsLiveStatus" style="margin:8px 0 14px;font-size:.92rem"><span class="warn" data-en="Querying live DNS…" data-ar="جارٍ الاستعلام المباشر عن DNS…">Querying live DNS…</span></div>
125
+ <table class="table" id="recordsTable">
126
+ <thead><tr><th data-en="Live" data-ar="مباشر">Live</th><th>Name / Host</th><th>Type</th><th>Value</th><th>TTL</th></tr></thead>
127
+ <tbody>
128
+ <tr data-record="_wab.webagentbridge.com" data-rtype="TXT" data-match="v=wab1">
129
+ <td class="live-cell"><span class="warn">…</span></td>
130
+ <td><code>_wab</code></td>
131
+ <td><code>TXT</code></td>
132
+ <td><code>"v=wab1; endpoint=https://www.webagentbridge.com/.well-known/wab.json"</code></td>
133
+ <td>3600</td>
134
+ </tr>
135
+ <tr data-record="_wab-agent.webagentbridge.com" data-rtype="TXT" data-match="v=wab1">
136
+ <td class="live-cell"><span class="warn">…</span></td>
137
+ <td><code>_wab-agent</code></td>
138
+ <td><code>TXT</code></td>
139
+ <td><code>"v=wab1; mcp=https://www.webagentbridge.com/api/v1/protocol; gateway=https://www.webagentbridge.com/api/v1"</code></td>
140
+ <td>3600</td>
141
+ </tr>
142
+ <tr data-record="_wab-trust.webagentbridge.com" data-rtype="TXT" data-match="v=wab1">
143
+ <td class="live-cell"><span class="warn">…</span></td>
144
+ <td><code>_wab-trust</code></td>
145
+ <td><code>TXT</code></td>
146
+ <td><code>"v=wab1; trust=https://www.webagentbridge.com/.well-known/wab.json; security=https://www.webagentbridge.com/.well-known/security.txt"</code></td>
147
+ <td>3600</td>
148
+ </tr>
149
+ <tr data-record="_dmarc.webagentbridge.com" data-rtype="TXT" data-match="v=DMARC1; p=quarantine">
150
+ <td class="live-cell"><span class="warn">…</span></td>
151
+ <td><code>_dmarc</code></td>
152
+ <td><code>TXT</code></td>
153
+ <td><code>"v=DMARC1; p=quarantine; rua=mailto:dmarc@webagentbridge.com; ruf=mailto:dmarc@webagentbridge.com; adkim=s; aspf=s; pct=100"</code></td>
154
+ <td>3600</td>
155
+ </tr>
156
+ <tr data-record="webagentbridge.com" data-rtype="TXT" data-match="v=spf1">
157
+ <td class="live-cell"><span class="warn">…</span></td>
158
+ <td><code>@</code> (apex)</td>
159
+ <td><code>TXT</code></td>
160
+ <td><code>"v=spf1 -all"</code></td>
161
+ <td>3600</td>
162
+ </tr>
163
+ <tr data-record="webagentbridge.com" data-rtype="CAA" data-match="letsencrypt.org">
164
+ <td class="live-cell"><span class="warn">…</span></td>
165
+ <td><code>@</code> (apex)</td>
166
+ <td><code>CAA</code></td>
167
+ <td><code>0 issue "letsencrypt.org"</code></td>
168
+ <td>3600</td>
169
+ </tr>
170
+ <tr data-record="webagentbridge.com" data-rtype="CAA" data-match="iodef">
171
+ <td class="live-cell"><span class="warn">…</span></td>
172
+ <td><code>@</code> (apex)</td>
173
+ <td><code>CAA</code></td>
174
+ <td><code>0 iodef "mailto:security@webagentbridge.com"</code></td>
175
+ <td>3600</td>
176
+ </tr>
177
+ </tbody>
178
+ </table>
179
+ <p style="margin-top:12px"><strong data-en="Verify after propagation:" data-ar="للتحقق بعد الانتشار:">Verify after propagation:</strong> <a href="#verifier" data-en="open the live verifier above" data-ar="استخدم المدقق المباشر بالأعلى">open the live verifier above</a> <span data-en="or run" data-ar="أو نفّذ"></span> <code>dig _wab.webagentbridge.com TXT +short</code></p>
180
+ </div>
181
+
182
+ <!-- ═══════════════ LIVE VERIFIER ═══════════════ -->
183
+ <div class="card" id="verifier">
184
+ <h3 data-en="Live Verifier (DNS over HTTPS)" data-ar="مدقق مباشر (DNS عبر HTTPS)">Live Verifier (DNS over HTTPS)</h3>
185
+ <p data-en="Enter any domain to query its _wab TXT record live from a public DoH resolver. This runs entirely in your browser — no data is sent to our servers." data-ar="أدخل أي نطاق لاستعلام سجل _wab TXT الخاص به مباشرة من خادم DoH عام. يعمل كاملاً في متصفحك — لا تُرسل أي بيانات إلى خوادمنا.">Enter any domain to query its <code>_wab</code> TXT record live from a public DoH resolver. This runs entirely in your browser — no data is sent to our servers.</p>
186
+ <div class="verifier">
187
+ <div class="row">
188
+ <div>
189
+ <label data-en="Domain" data-ar="النطاق">Domain</label>
190
+ <input id="dnsDomain" placeholder="example.com" value="webagentbridge.com">
191
+ </div>
192
+ <div>
193
+ <label data-en="Resolver" data-ar="المحلل">Resolver</label>
194
+ <select id="dnsResolver">
195
+ <option value="https://cloudflare-dns.com/dns-query">Cloudflare (1.1.1.1)</option>
196
+ <option value="https://dns.google/resolve">Google (8.8.8.8)</option>
197
+ </select>
198
+ </div>
199
+ </div>
200
+ <button class="btn" onclick="verifyDns()" data-en="Verify _wab Record" data-ar="تحقق من سجل _wab">Verify _wab Record</button>
201
+ <button class="btn secondary" onclick="copyExample()" data-en="Copy Example Record" data-ar="انسخ سجلاً نموذجياً">Copy Example Record</button>
202
+ <div id="dnsStatus" style="margin-top:10px;font-size:.92rem"></div>
203
+ <pre id="dnsOut">{}</pre>
204
+ </div>
205
+ </div>
206
+
207
+ <!-- ═══════════════ PRIVACY MODEL ═══════════════ -->
208
+ <div class="card" id="privacy">
209
+ <h3 data-en="DNS Privacy Model — what DoH does and does not protect" data-ar="نموذج خصوصية DNS — ما الذي يحميه DoH وما لا يحميه">DNS Privacy Model — what DoH does and does not protect</h3>
210
+ <p data-en="WAB Discovery never uses plain UDP DNS. Every lookup of _wab.example.com uses DNS over HTTPS (DoH), so the query is encrypted between the agent and the resolver. This is a real privacy upgrade — but it is not perfect, and we want you to understand the exact threat model." data-ar="لا يستخدم اكتشاف WAB أبداً DNS التقليدي عبر UDP. كل استعلام لـ _wab.example.com يتم عبر DNS over HTTPS (DoH)، فيكون مشفراً بين الوكيل والمحلل. هذه تحسين خصوصية حقيقي — لكنه ليس مثالياً، ونريد أن تفهم نموذج التهديد بدقة.">WAB Discovery never uses plain UDP DNS. Every lookup of <code>_wab.example.com</code> uses DNS over HTTPS (DoH), so the query is encrypted between the agent and the resolver.</p>
211
+ <table class="table">
212
+ <thead><tr><th data-en="Threat" data-ar="التهديد">Threat</th><th data-en="Plain DNS (UDP/53)" data-ar="DNS عادي (UDP/53)">Plain DNS</th><th>WAB DoH</th></tr></thead>
213
+ <tbody>
214
+ <tr><td data-en="ISP / network observer sees lookup" data-ar="مزود الإنترنت يرى الاستعلام">ISP / network observer sees lookup</td><td><span class="danger">✗ visible cleartext</span></td><td><span class="ok">✓ encrypted (TLS 1.3)</span></td></tr>
215
+ <tr><td data-en="DoH provider sees lookup" data-ar="مزود DoH يرى الاستعلام">DoH provider sees lookup</td><td><span class="warn">— (not used)</span></td><td><span class="warn">⚠ visible to chosen resolver</span></td></tr>
216
+ <tr><td data-en="Reply tampered in transit (cache poisoning)" data-ar="تلاعب بالرد أثناء النقل">Reply tampered in transit</td><td><span class="danger">✗ trivial on-path</span></td><td><span class="ok">✓ TLS prevents on-path tamper</span></td></tr>
217
+ <tr><td data-en="Authoritative record forged at zone level" data-ar="تزوير السجل عند الخادم الرسمي">Authoritative record forged at zone</td><td><span class="danger">✗ no signature</span></td><td><span class="warn" id="dnssecRowState">⚠ DNSSEC recommended</span></td></tr>
218
+ <tr><td data-en="Provider link leaks via certificate" data-ar="تسرب الهوية عبر الشهادة">Provider link leaks via certificate</td><td>—</td><td><span class="ok">✓ certificate pinning roadmap</span></td></tr>
219
+ </tbody>
220
+ </table>
221
+ <p style="margin-top:12px"><strong data-en="Bottom line:" data-ar="الخلاصة:">Bottom line:</strong> <span data-en="DoH moves the trust point from your ISP to your DoH resolver. That is a strict improvement for most users, but you still pick whom to trust. Combine DoH with DNSSEC and certificate pinning for the strongest privacy posture." data-ar="ينقل DoH نقطة الثقة من مزود الإنترنت إلى مزود DoH. هذا تحسين صارم لمعظم المستخدمين، لكنك ما زلت تختار من تثق به. اجمع DoH مع DNSSEC وتثبيت الشهادات للحصول على أقوى وضعية خصوصية.">DoH moves the trust point from your ISP to your DoH resolver — a strict improvement, but you still pick whom to trust. Combine DoH with DNSSEC and certificate pinning for the strongest posture.</span></p>
222
+ <p><strong data-en="DNSSEC live status for webagentbridge.com:" data-ar="حالة DNSSEC المباشرة لـ webagentbridge.com:">DNSSEC live status for webagentbridge.com:</strong> <span id="dnssecLiveStatus" class="warn">…</span></p>
223
+ </div>
224
+
225
+ <!-- ═══════════════ SILENT HANDSHAKE ═══════════════ -->
226
+ <div class="card" id="silent-handshake">
227
+ <h3 data-en="Silent Handshake — agent-aware sites, zero cookie banners" data-ar="المصافحة الصامتة — مواقع تفهم الوكلاء بدون نوافذ كوكيز">Silent Handshake — agent-aware sites, zero cookie banners</h3>
228
+ <p data-en="When a WAB-aware site advertises _wab and _wab-trust over DNS, the visiting agent and the site can negotiate intent in the background — no privacy popup, no cookie banner, no consent click-fest. The site declares 'I respect your agent, here is the contract' once, in DNS, signed and cacheable." data-ar="عندما يعلن موقع متوافق مع WAB عن _wab و _wab-trust في DNS، يمكن للوكيل الزائر والموقع أن يتفاوضا في الخلفية — بدون نوافذ خصوصية ولا بانر كوكيز ولا نقرات موافقة. يعلن الموقع مرة واحدة في DNS: «أنا أحترم وكيلك، هذا هو العقد».">When a WAB-aware site advertises <code>_wab</code> and <code>_wab-trust</code> over DNS, the agent and site negotiate intent in the background — no privacy popup, no cookie banner, no consent click-fest.</p>
229
+ <ol>
230
+ <li data-en="Agent resolves _wab.{site} over DoH → discovers wab.json endpoint." data-ar="يستعلم الوكيل عن _wab.{site} عبر DoH → يكتشف نقطة wab.json.">Agent resolves <code>_wab.{site}</code> over DoH → discovers <code>wab.json</code> endpoint.</li>
231
+ <li data-en="Agent resolves _wab-trust.{site} → reads contract: data scope, rate limits, complaint channel." data-ar="يستعلم عن _wab-trust.{site} → يقرأ العقد: نطاق البيانات، الحدود، قناة الشكوى.">Agent resolves <code>_wab-trust.{site}</code> → reads contract: data scope, rate limits, complaint channel.</li>
232
+ <li data-en="Agent fetches wab.json, signs request with its key, site responds with structured commands." data-ar="يجلب الوكيل wab.json ويوقّع الطلب بمفتاحه، فيرد الموقع بأوامر بنيوية.">Agent fetches <code>wab.json</code>, signs request with its key, site responds with structured commands.</li>
233
+ <li data-en="Both sides record outcome to their audit ledger. No human pixels harmed." data-ar="يسجّل الطرفان النتيجة في سجل التدقيق. بدون أي نوافذ مزعجة للمستخدم.">Both sides record outcome to their audit ledger. No human pixels harmed.</li>
234
+ </ol>
235
+ <p style="margin-top:10px"><strong data-en="SEO upside:" data-ar="مكسب السيو:">SEO upside:</strong> <span data-en="WAB-discoverable sites get prioritized by agent traffic, return data faster (less scraping overhead), and reduce server load. Sites that opt in are surfaced first in agent search results — the opposite of the cookie-wall tax." data-ar="المواقع المُكتشَفة عبر WAB تحصل على أولوية في زيارات الوكلاء، وترد بالبيانات أسرع (دون عبء الكشط)، وتخفف حمل السيرفر. المواقع التي تنضم تظهر أولاً في نتائج الوكلاء — عكس ضريبة جدار الكوكيز.">WAB-discoverable sites get prioritized by agent traffic, return data faster (less scraping overhead), and reduce server load. Opt-in sites surface first in agent search results — the opposite of the cookie-wall tax.</span></p>
236
+ </div>
237
+
238
+ <!-- ═══════════════ SETUP GUIDES ═══════════════ -->
239
+ <div class="grid" id="setup">
240
+ <div class="card">
241
+ <h3>1. Cloudflare</h3>
242
+ <ol>
243
+ <li data-en="Open Cloudflare dashboard and select your domain." data-ar="افتح لوحة Cloudflare واختر نطاقك.">Open Cloudflare dashboard and select your domain.</li>
244
+ <li data-en="Go to DNS → Records → Add record." data-ar="انتقل إلى DNS → Records → Add record.">Go to <b>DNS → Records → Add record</b>.</li>
245
+ <li data-en="Type: TXT, Name: _wab" data-ar="النوع: TXT، الاسم: _wab">Type: <code>TXT</code>, Name: <code>_wab</code></li>
246
+ <li data-en="Content: v=wab1; endpoint=https://yourdomain.com/.well-known/wab.json" data-ar="المحتوى: v=wab1; endpoint=https://yourdomain.com/.well-known/wab.json">Content: <code>v=wab1; endpoint=https://yourdomain.com/.well-known/wab.json</code></li>
247
+ <li data-en="Leave TTL on Auto and Save." data-ar="اترك TTL على Auto واحفظ.">Leave TTL on <b>Auto</b> and Save.</li>
248
+ </ol>
249
+ </div>
250
+
251
+ <div class="card">
252
+ <h3>2. cPanel (Shared Hosting)</h3>
253
+ <ol>
254
+ <li data-en="cPanel → Domains → Zone Editor → Manage." data-ar="cPanel → Domains → Zone Editor → Manage.">cPanel → <b>Domains → Zone Editor → Manage</b>.</li>
255
+ <li data-en="Add Record → Add 'TXT' Record." data-ar="Add Record → Add 'TXT' Record."><b>Add Record → Add "TXT" Record</b>.</li>
256
+ <li data-en="Name: _wab (cPanel appends your domain automatically)." data-ar="Name: _wab (سيلحق cPanel نطاقك تلقائياً).">Name: <code>_wab</code> (cPanel appends your domain automatically).</li>
257
+ <li data-en="Record: v=wab1; endpoint=https://yourdomain.com/.well-known/wab.json" data-ar="Record: v=wab1; endpoint=https://yourdomain.com/.well-known/wab.json">Record: <code>v=wab1; endpoint=https://yourdomain.com/.well-known/wab.json</code></li>
258
+ <li data-en="Click Save Record." data-ar="انقر Save Record.">Click <b>Save Record</b>.</li>
259
+ </ol>
260
+ </div>
261
+
262
+ <div class="card">
263
+ <h3>3. GoDaddy</h3>
264
+ <ol>
265
+ <li data-en="Domain Portfolio → click your domain." data-ar="Domain Portfolio → اضغط نطاقك.">Domain Portfolio → click your domain.</li>
266
+ <li data-en="DNS tab → DNS Records → Add New Record." data-ar="تبويب DNS → DNS Records → Add New Record.">DNS tab → <b>DNS Records → Add New Record</b>.</li>
267
+ <li>Type: <code>TXT</code>, Name: <code>_wab</code></li>
268
+ <li data-en="Value: v=wab1; endpoint=https://yourdomain.com/.well-known/wab.json" data-ar="Value: v=wab1; endpoint=https://yourdomain.com/.well-known/wab.json">Value: <code>v=wab1; endpoint=https://yourdomain.com/.well-known/wab.json</code></li>
269
+ <li data-en="Save (TTL default = 1 Hour is fine)." data-ar="احفظ (الإعداد الافتراضي 1 Hour مناسب).">Save (TTL default = 1 Hour is fine).</li>
270
+ </ol>
271
+ </div>
272
+
273
+ <div class="card">
274
+ <h3>4. Namecheap</h3>
275
+ <ol>
276
+ <li data-en="Domain List → Manage → Advanced DNS." data-ar="Domain List → Manage → Advanced DNS.">Domain List → <b>Manage → Advanced DNS</b>.</li>
277
+ <li data-en="Host Records → Add New Record → TXT Record." data-ar="Host Records → Add New Record → TXT Record.">Host Records → <b>Add New Record → TXT Record</b>.</li>
278
+ <li>Host: <code>_wab</code></li>
279
+ <li>Value: <code>v=wab1; endpoint=https://yourdomain.com/.well-known/wab.json</code></li>
280
+ <li data-en="Save with the green checkmark." data-ar="احفظ بأيقونة الصح الخضراء.">Save with the green checkmark.</li>
281
+ </ol>
282
+ </div>
283
+
284
+ <div class="card">
285
+ <h3>5. AWS Route 53</h3>
286
+ <ol>
287
+ <li data-en="Route 53 → Hosted zones → your domain → Create record." data-ar="Route 53 → Hosted zones → نطاقك → Create record.">Route 53 → <b>Hosted zones → your domain → Create record</b>.</li>
288
+ <li data-en="Record name: _wab — Record type: TXT" data-ar="Record name: _wab — Record type: TXT">Record name: <code>_wab</code> — Record type: <code>TXT</code></li>
289
+ <li data-en='Value (with quotes): "v=wab1; endpoint=https://yourdomain.com/.well-known/wab.json"' data-ar='Value (مع علامات الاقتباس): "v=wab1; endpoint=https://yourdomain.com/.well-known/wab.json"'>Value (with quotes): <code>"v=wab1; endpoint=https://yourdomain.com/.well-known/wab.json"</code></li>
290
+ <li>TTL: <code>300</code>–<code>3600</code></li>
291
+ <li data-en="Click Create records." data-ar="انقر Create records.">Click <b>Create records</b>.</li>
292
+ </ol>
293
+ </div>
294
+
295
+ <div class="card">
296
+ <h3>6. Google Domains / Squarespace, OVH, etc.</h3>
297
+ <p data-en="The pattern is identical across all providers: create a TXT record with host _wab and the v=wab1; endpoint=… value. If your provider asks for the FQDN, use _wab.yourdomain.com. Some panels strip the trailing dot — that is OK." data-ar="النمط متطابق لدى جميع المزودين: أنشئ سجل TXT بالمضيف _wab والقيمة v=wab1; endpoint=… . إذا طلب المزود الاسم الكامل FQDN، اكتب _wab.yourdomain.com. بعض اللوحات تحذف النقطة الأخيرة وهذا أمر طبيعي.">The pattern is identical across all providers: create a TXT record with host <code>_wab</code> and the <code>v=wab1; endpoint=…</code> value. If your provider asks for the FQDN, use <code>_wab.yourdomain.com</code>. Some panels strip the trailing dot — that is OK.</p>
298
+ </div>
299
+ </div>
300
+
301
+ <!-- ═══════════════ VERIFY CLI ═══════════════ -->
302
+ <div class="card">
303
+ <h3 data-en="Verify from the command line" data-ar="التحقق من سطر الأوامر">Verify from the command line</h3>
304
+ <p data-en="DNS propagation can take a few minutes up to 48 hours. Verify with:" data-ar="قد يستغرق انتشار DNS من بضع دقائق إلى 48 ساعة. تحقق بما يلي:">DNS propagation can take a few minutes up to 48 hours. Verify with:</p>
305
+ <pre># macOS / Linux
306
+ dig TXT _wab.yourdomain.com +short
307
+
308
+ # Windows
309
+ nslookup -type=TXT _wab.yourdomain.com
310
+
311
+ # Anywhere (DoH via curl)
312
+ curl -s -H 'accept: application/dns-json' \
313
+ 'https://cloudflare-dns.com/dns-query?name=_wab.yourdomain.com&type=TXT'</pre>
314
+ <p data-en="Expected output:" data-ar="الناتج المتوقع:">Expected output:</p>
315
+ <pre>"v=wab1; endpoint=https://yourdomain.com/.well-known/wab.json"</pre>
316
+ </div>
317
+
318
+ <!-- ═══════════════ TROUBLESHOOTING ═══════════════ -->
319
+ <div class="card" id="troubleshoot">
320
+ <h3 data-en="Troubleshooting" data-ar="حل المشاكل">Troubleshooting</h3>
321
+ <ul>
322
+ <li data-en="Got an empty answer? Wait 5–30 minutes for propagation, or flush your local DNS cache." data-ar="إجابة فارغة؟ انتظر 5 إلى 30 دقيقة للانتشار، أو امسح ذاكرة DNS المحلية.">Got an empty answer? Wait 5–30 minutes for propagation, or flush your local DNS cache.</li>
323
+ <li data-en="Some panels wrap the value in extra quotes — that is fine. Resolvers strip them." data-ar="بعض اللوحات تضيف علامات اقتباس إضافية — لا مشكلة. المحللات تزيلها.">Some panels wrap the value in extra quotes — that is fine. Resolvers strip them.</li>
324
+ <li data-en="Make sure the endpoint URL is HTTPS and returns a valid wab.json (Content-Type: application/json)." data-ar="تأكد أن endpoint يبدأ بـ HTTPS ويعيد ملف wab.json صالح بنوع application/json.">Make sure the <code>endpoint</code> URL is HTTPS and returns a valid <code>wab.json</code> (Content-Type: <code>application/json</code>).</li>
325
+ <li data-en="Do not put the full domain in the Name field unless your panel explicitly requires FQDN — that creates _wab.yourdomain.com.yourdomain.com." data-ar="لا تكتب النطاق الكامل في حقل Name إلا إذا طلب المزود ذلك صراحة — وإلا ستحصل على _wab.yourdomain.com.yourdomain.com.">Do not put the full domain in the Name field unless your panel explicitly requires FQDN — that creates <code>_wab.yourdomain.com.yourdomain.com</code>.</li>
326
+ <li data-en="If using DNSSEC, no extra step is required — TXT records are protected automatically." data-ar="إذا كنت تستخدم DNSSEC، لا حاجة لخطوة إضافية — سجلات TXT محمية تلقائياً.">If using DNSSEC, no extra step is required — TXT records are protected automatically.</li>
327
+ </ul>
328
+ </div>
329
+
330
+ <!-- ═══════════════ REPO LINKS ═══════════════ -->
331
+ <div class="card" id="repo-links">
332
+ <h3 data-en="Full documentation in the repo" data-ar="التوثيق الكامل في الريبو">Full documentation in the repo</h3>
333
+ <p data-en="The most extensive guides, including provider-specific edge cases and the full discovery protocol spec, live in the GitHub repository:" data-ar="أكثر الأدلة تفصيلاً، بما في ذلك حالات خاصة لكل مزود والمواصفات الكاملة للبروتوكول، موجودة في مستودع GitHub:">The most extensive guides, including provider-specific edge cases and the full discovery protocol spec, live in the GitHub repository:</p>
334
+ <ul>
335
+ <li><a href="https://github.com/abokenan444/web-agent-bridge/blob/master/DNS-DISCOVERY.md" target="_blank" rel="noopener">DNS-DISCOVERY.md (English)</a></li>
336
+ <li><a href="https://github.com/abokenan444/web-agent-bridge/blob/master/DNS-DISCOVERY.ar.md" target="_blank" rel="noopener">DNS-DISCOVERY.ar.md (العربية)</a></li>
337
+ <li><a href="https://github.com/abokenan444/web-agent-bridge/blob/master/docs/SPEC.md#4-discovery-protocol" target="_blank" rel="noopener">docs/SPEC.md — Discovery Protocol §4</a></li>
338
+ <li><a href="/.well-known/wab.json" target="_blank">/.well-known/wab.json (this site's capabilities)</a></li>
339
+ </ul>
340
+ </div>
341
+
342
+ </div>
343
+
344
+ <script>
345
+ // ═══════════ Bilingual toggle ═══════════
346
+ function setLang(lang){
347
+ const isAr = lang === 'ar';
348
+ document.documentElement.lang = isAr ? 'ar' : 'en';
349
+ document.documentElement.dir = isAr ? 'rtl' : 'ltr';
350
+ document.getElementById('enBtn').classList.toggle('active', !isAr);
351
+ document.getElementById('arBtn').classList.toggle('active', isAr);
352
+ document.querySelectorAll('[data-en]').forEach(el=>{
353
+ el.textContent = isAr ? (el.getAttribute('data-ar') || el.textContent) : (el.getAttribute('data-en') || el.textContent);
354
+ });
355
+ }
356
+
357
+ // ═══════════ Live DoH Verifier ═══════════
358
+ async function verifyDns(){
359
+ const domain = (document.getElementById('dnsDomain').value || '').trim().replace(/^https?:\/\//,'').replace(/\/.*$/,'');
360
+ const resolver = document.getElementById('dnsResolver').value;
361
+ const status = document.getElementById('dnsStatus');
362
+ const out = document.getElementById('dnsOut');
363
+ if(!domain){ status.innerHTML = '<span class="danger">Please enter a domain.</span>'; return; }
364
+ const fqdn = '_wab.' + domain;
365
+ status.innerHTML = '<span class="warn">Querying ' + fqdn + ' …</span>';
366
+ out.textContent = '';
367
+ try {
368
+ const url = resolver + '?name=' + encodeURIComponent(fqdn) + '&type=TXT';
369
+ const res = await fetch(url, { headers: { 'accept': 'application/dns-json' } });
370
+ const data = await res.json();
371
+ out.textContent = JSON.stringify(data, null, 2);
372
+ const answers = (data.Answer || []).filter(a => a.type === 16);
373
+ if (!answers.length) {
374
+ status.innerHTML = '<span class="danger">No _wab TXT record found for <b>' + domain + '</b>. The domain has not enabled WAB DNS Discovery (yet).</span>';
375
+ return;
376
+ }
377
+ const value = answers.map(a => (a.data || '').replace(/^"|"$/g,'').replace(/" "/g,'')).join(' ');
378
+ const versionMatch = /v=([^;\s]+)/.exec(value);
379
+ const endpointMatch = /endpoint=([^;\s]+)/.exec(value);
380
+ if (versionMatch && endpointMatch && versionMatch[1].startsWith('wab')) {
381
+ status.innerHTML = '<span class="ok">✓ Valid WAB record found. Version: <b>' + versionMatch[1] + '</b> · Endpoint: <a href="' + endpointMatch[1] + '" target="_blank" style="color:#7dd3fc">' + endpointMatch[1] + '</a></span>';
382
+ } else {
383
+ status.innerHTML = '<span class="warn">TXT record found but it does not match the WAB format (v=wab1; endpoint=…).</span>';
384
+ }
385
+ } catch (err) {
386
+ status.innerHTML = '<span class="danger">Lookup failed: ' + (err && err.message || err) + '</span>';
387
+ }
388
+ }
389
+
390
+ function copyExample(){
391
+ const txt = 'v=wab1; endpoint=https://yourdomain.com/.well-known/wab.json';
392
+ navigator.clipboard.writeText(txt).then(()=>{
393
+ const s = document.getElementById('dnsStatus');
394
+ s.innerHTML = '<span class="ok">✓ Example record copied to clipboard.</span>';
395
+ });
396
+ }
397
+
398
+ // ═══════════ Canonical records — live status ═══════════
399
+ const RR_TYPE = { TXT: 16, CAA: 257, A: 1, AAAA: 28, CNAME: 5 };
400
+
401
+ function _decodeCAARdata(hex){
402
+ // RFC 8659: 1 byte flags, 1 byte tag-length, tag, value (rest)
403
+ try {
404
+ const bytes = hex.replace(/\\#\s*\d+\s*/, '').replace(/\s+/g, '');
405
+ const buf = bytes.match(/.{1,2}/g).map(b => parseInt(b, 16));
406
+ const tagLen = buf[1];
407
+ let tag = '', val = '';
408
+ for (let i = 0; i < tagLen; i++) tag += String.fromCharCode(buf[2 + i]);
409
+ for (let i = 2 + tagLen; i < buf.length; i++) val += String.fromCharCode(buf[i]);
410
+ return { tag, value: val };
411
+ } catch { return null; }
412
+ }
413
+
414
+ function _normalizeAnswer(answer, type){
415
+ const data = answer.data || '';
416
+ if (type === 'CAA') {
417
+ const decoded = _decodeCAARdata(data);
418
+ if (decoded) return decoded.tag + ' ' + decoded.value;
419
+ // Some resolvers return the parsed form already (e.g. '0 issue "letsencrypt.org"')
420
+ return data;
421
+ }
422
+ return data.replace(/^"|"$/g, '').replace(/"\s*"/g, '');
423
+ }
424
+
425
+ async function _doh(name, type){
426
+ // do=1 asks Cloudflare to set the AD flag when the answer is DNSSEC-validated.
427
+ const url = 'https://cloudflare-dns.com/dns-query?name=' +
428
+ encodeURIComponent(name) + '&type=' + encodeURIComponent(type) + '&do=1';
429
+ const res = await fetch(url, { headers: { 'accept': 'application/dns-json' } });
430
+ const data = await res.json();
431
+ const want = RR_TYPE[type];
432
+ const answers = (data.Answer || []).filter(a => a.type === want)
433
+ .map(a => _normalizeAnswer(a, type));
434
+ // Attach AD flag (DNSSEC validated) as a non-enumerable property
435
+ Object.defineProperty(answers, '_ad', { value: !!data.AD, enumerable: false });
436
+ return answers;
437
+ }
438
+
439
+ async function checkDnssecForWab(){
440
+ const el = document.getElementById('dnssecLiveStatus');
441
+ const rowState = document.getElementById('dnssecRowState');
442
+ if (!el) return;
443
+ try {
444
+ const ans = await _doh('_wab.webagentbridge.com', 'TXT');
445
+ if (ans._ad) {
446
+ el.className = 'ok';
447
+ el.textContent = '✓ DNSSEC validated (AD=1) at resolver';
448
+ if (rowState) { rowState.className = 'ok'; rowState.textContent = '✓ DNSSEC validated'; }
449
+ } else {
450
+ el.className = 'warn';
451
+ el.textContent = '⚠ DNSSEC not yet enabled on this zone (AD=0). Roadmap: enable DS at registrar.';
452
+ }
453
+ } catch {
454
+ el.className = 'warn';
455
+ el.textContent = '… could not verify (DoH unreachable)';
456
+ }
457
+ }
458
+
459
+ async function checkCanonicalRecords(){
460
+ const rows = document.querySelectorAll('#recordsTable tr[data-record]');
461
+ const summary = document.getElementById('recordsLiveStatus');
462
+ let pass = 0, fail = 0;
463
+ const tasks = Array.from(rows).map(async (row) => {
464
+ const cell = row.querySelector('.live-cell');
465
+ const name = row.dataset.record;
466
+ const type = row.dataset.rtype;
467
+ const match = row.dataset.match;
468
+ try {
469
+ const answers = await _doh(name, type);
470
+ const hit = answers.some(a => a.toLowerCase().includes(match.toLowerCase()));
471
+ if (hit) {
472
+ cell.innerHTML = '<span class="ok" title="Verified live via Cloudflare DoH">✓ live</span>';
473
+ pass++;
474
+ } else {
475
+ cell.innerHTML = '<span class="danger" title="Record not yet propagated or missing">✗ missing</span>';
476
+ fail++;
477
+ }
478
+ } catch (err) {
479
+ cell.innerHTML = '<span class="warn" title="Lookup failed">… error</span>';
480
+ }
481
+ });
482
+ await Promise.allSettled(tasks);
483
+ const total = pass + fail;
484
+ summary.innerHTML = '<span class="' + (fail === 0 ? 'ok' : 'warn') + '">' +
485
+ (fail === 0 ? '✓ All ' + total + ' canonical records verified live (Cloudflare DoH).'
486
+ : '⚠ ' + pass + '/' + total + ' records live — ' + fail + ' missing or propagating.') + '</span>';
487
+ }
488
+
489
+ document.addEventListener('DOMContentLoaded', () => {
490
+ // Don't block the page; run the live checks in the background.
491
+ checkCanonicalRecords().catch(()=>{});
492
+ checkDnssecForWab().catch(()=>{});
493
+ });
494
+ </script>
495
+
496
+ <script>
497
+ // navbar scroll background (consistent with other pages)
498
+ const navbar = document.getElementById('navbar');
499
+ window.addEventListener('scroll', () => {
500
+ if (!navbar) return;
501
+ navbar.style.background = window.scrollY > 50
502
+ ? 'rgba(7, 13, 25, 0.92)'
503
+ : 'rgba(7, 13, 25, 0.78)';
504
+ });
505
+ </script>
506
+ </body>
507
+ </html>