remote-webview-debugger 0.1.0 → 0.2.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 (55) hide show
  1. package/CHANGELOG.md +20 -0
  2. package/CHANGELOG.zh-CN.md +20 -0
  3. package/README.ar.md +185 -0
  4. package/README.de.md +169 -0
  5. package/README.es.md +169 -0
  6. package/README.fr.md +169 -0
  7. package/README.ja.md +169 -0
  8. package/README.ko.md +169 -0
  9. package/README.md +68 -14
  10. package/README.pt-BR.md +169 -0
  11. package/README.ru.md +169 -0
  12. package/README.zh-CN.md +69 -14
  13. package/README.zh-TW.md +169 -0
  14. package/dist/index.d.ts +216 -8
  15. package/dist/index.mjs +2479 -2873
  16. package/dist/index.mjs.map +1 -1
  17. package/dist/locales/ar.d.ts +4 -0
  18. package/dist/locales/ar.js +2 -0
  19. package/dist/locales/ar.mjs +150 -0
  20. package/dist/locales/ar.mjs.map +1 -0
  21. package/dist/locales/de.d.ts +4 -0
  22. package/dist/locales/de.js +2 -0
  23. package/dist/locales/de.mjs +150 -0
  24. package/dist/locales/de.mjs.map +1 -0
  25. package/dist/locales/es.d.ts +4 -0
  26. package/dist/locales/es.js +2 -0
  27. package/dist/locales/es.mjs +150 -0
  28. package/dist/locales/es.mjs.map +1 -0
  29. package/dist/locales/fr.d.ts +4 -0
  30. package/dist/locales/fr.js +2 -0
  31. package/dist/locales/fr.mjs +150 -0
  32. package/dist/locales/fr.mjs.map +1 -0
  33. package/dist/locales/ja.d.ts +4 -0
  34. package/dist/locales/ja.js +2 -0
  35. package/dist/locales/ja.mjs +150 -0
  36. package/dist/locales/ja.mjs.map +1 -0
  37. package/dist/locales/ko.d.ts +4 -0
  38. package/dist/locales/ko.js +2 -0
  39. package/dist/locales/ko.mjs +156 -0
  40. package/dist/locales/ko.mjs.map +1 -0
  41. package/dist/locales/pt.d.ts +4 -0
  42. package/dist/locales/pt.js +2 -0
  43. package/dist/locales/pt.mjs +150 -0
  44. package/dist/locales/pt.mjs.map +1 -0
  45. package/dist/locales/ru.d.ts +4 -0
  46. package/dist/locales/ru.js +2 -0
  47. package/dist/locales/ru.mjs +150 -0
  48. package/dist/locales/ru.mjs.map +1 -0
  49. package/dist/locales/zh-TW.d.ts +4 -0
  50. package/dist/locales/zh-TW.js +2 -0
  51. package/dist/locales/zh-TW.mjs +150 -0
  52. package/dist/locales/zh-TW.mjs.map +1 -0
  53. package/dist/sdk.js +24 -326
  54. package/dist/sdk.js.map +1 -1
  55. package/package.json +8 -2
package/CHANGELOG.md CHANGED
@@ -4,6 +4,26 @@ English | [简体中文](CHANGELOG.zh-CN.md)
4
4
 
5
5
  The page SDK, published to npm as [`remote-webview-debugger`](https://www.npmjs.com/package/remote-webview-debugger). Tags: `sdk-vX.Y.Z`.
6
6
 
7
+ ## v0.2.0 (2026-11-03)
8
+
9
+ [compare changes](https://github.com/ZaneL1u/remote-webview-debugger/compare/sdk-v0.1.0...sdk-v0.2.0)
10
+
11
+ ### 🚀 Enhancements
12
+
13
+ - language packs in 11 languages, your own packs and styles ([9febf83](https://github.com/ZaneL1u/remote-webview-debugger/commit/9febf83))
14
+ - "Request assistance" and "Assisting" instead of "Get help", in every language ([73637cb](https://github.com/ZaneL1u/remote-webview-debugger/commit/73637cb))
15
+
16
+ ### 🔥 Performance
17
+
18
+ - mangle the whole bundle and minify the UI's stylesheets ([555779e](https://github.com/ZaneL1u/remote-webview-debugger/commit/555779e))
19
+
20
+ ### 📖 Documentation
21
+
22
+ - README and docs in Traditional Chinese, Japanese, Spanish, French, Russian and Arabic ([9ba0aae](https://github.com/ZaneL1u/remote-webview-debugger/commit/9ba0aae))
23
+ - languages and styling, in every doc language ([d17b1f5](https://github.com/ZaneL1u/remote-webview-debugger/commit/d17b1f5))
24
+ - Korean, German and Brazilian Portuguese, the same 11 languages as the UI ([0161fed](https://github.com/ZaneL1u/remote-webview-debugger/commit/0161fed))
25
+ - "Request assistance" and "Assisting" instead of "Get help" ([09f9f1c](https://github.com/ZaneL1u/remote-webview-debugger/commit/09f9f1c))
26
+
7
27
  ## v0.1.0 (2026-11-03)
8
28
 
9
29
  First release.
@@ -4,6 +4,26 @@
4
4
 
5
5
  页面 SDK,npm 包名 [`remote-webview-debugger`](https://www.npmjs.com/package/remote-webview-debugger)。tag 形如 `sdk-vX.Y.Z`。
6
6
 
7
+ ## v0.2.0 (2026-11-03)
8
+
9
+ [对比变更](https://github.com/ZaneL1u/remote-webview-debugger/compare/sdk-v0.1.0...sdk-v0.2.0)
10
+
11
+ ### 🚀 新功能
12
+
13
+ - 手机端界面支持 11 种语言:自动选择并逐级回退、按需加载、可注册自定义语言包和覆盖文案、阿拉伯语从右到左排版;样式可用 CSS 变量、run({ style }) 和 ::part 覆盖 ([9febf83](https://github.com/ZaneL1u/remote-webview-debugger/commit/9febf83))
14
+ - 「求助」改为「请求协助」,设备状态显示为「协助中」,11 种语言的手机界面、控制台和面向 agent 的文案一起调整 ([73637cb](https://github.com/ZaneL1u/remote-webview-debugger/commit/73637cb))
15
+
16
+ ### 🔥 性能
17
+
18
+ - sdk.js 体积减小约 10%(gzip 后 85.3 KB → 76.9 KB):修复了一处阻止整体混淆的直接 eval,并压缩了界面样式 ([555779e](https://github.com/ZaneL1u/remote-webview-debugger/commit/555779e))
19
+
20
+ ### 📖 文档
21
+
22
+ - README and docs in Traditional Chinese, Japanese, Spanish, French, Russian and Arabic ([9ba0aae](https://github.com/ZaneL1u/remote-webview-debugger/commit/9ba0aae))
23
+ - 文档:说明 11 种语言、语言包加载与自定义、样式覆盖(CSS 变量、run({ style })、::part),并同步到各语言译本 ([d17b1f5](https://github.com/ZaneL1u/remote-webview-debugger/commit/d17b1f5))
24
+ - 文档新增韩语、德语、巴西葡萄牙语译本,与界面的 11 种语言一致;所有文档的语言切换行列出全部语言 ([0161fed](https://github.com/ZaneL1u/remote-webview-debugger/commit/0161fed))
25
+ - 文档中「求助」改为「请求协助」,设备状态改为「协助中」,11 种语言同步 ([09f9f1c](https://github.com/ZaneL1u/remote-webview-debugger/commit/09f9f1c))
26
+
7
27
  ## v0.1.0 (2026-11-03)
8
28
 
9
29
  首个版本。
package/README.ar.md ADDED
@@ -0,0 +1,185 @@
1
+ <!-- i18n-source: d9a31993ea867d3ef7058e7d637886f38a6ee3e1 -->
2
+ [English](README.md) | [简体中文](README.zh-CN.md) | [繁體中文](README.zh-TW.md) | [日本語](README.ja.md) | [한국어](README.ko.md) | [Español](README.es.md) | [Français](README.fr.md) | [Deutsch](README.de.md) | [Português (Brasil)](README.pt-BR.md) | [Русский](README.ru.md) | العربية
3
+
4
+ <div dir="rtl">
5
+
6
+ # SDK الصفحة لـ RWD (`sdk/`)
7
+
8
+ ملف JS واحد تحمّله صفحة H5 أو WebView داخل تطبيق، ليتمكّن وكيل ذكاء اصطناعي من فحص الصفحة وتشغيلها عبر بوابة RWD (`gateway/`) و MCP. البروتوكول: [`docs/protocol.ar.md`](../docs/protocol.ar.md)؛ البنية: [`docs/architecture.ar.md`](../docs/architecture.ar.md).
9
+
10
+ <div dir="ltr">
11
+
12
+ ```html
13
+ <script src="https://cdn.jsdelivr.net/npm/remote-webview-debugger@0.1.0/dist/sdk.js"></script>
14
+ <script>
15
+ RemoteWebviewDebugger.run("https://rwd.example.com/v1", "rwd_pk_xxxxxxxx", {
16
+ userId: "u-42", // اختياري
17
+ deviceId: "…", // اختياري؛ يمرّره المضيف الأصلي الذي يحقن SDK
18
+ helpButton: true, // اختياري؛ يُظهر زر «طلب المساعدة»
19
+ app: { name: "Shop", version: "3.2.0" },
20
+ lang: "en", // اختياري؛ وسم لغة، والافتراضي من لغات المتصفح
21
+ }).then(({ deviceCode, status }) => console.log(deviceCode, status))
22
+ </script>
23
+ ```
24
+
25
+ </div>
26
+
27
+ ## الحصول على SDK
28
+
29
+ منشور على npm باسم [`remote-webview-debugger`](https://www.npmjs.com/package/remote-webview-debugger)؛ الإصدارات والتغييرات: [CHANGELOG](CHANGELOG.md).
30
+
31
+ | الاستخدام | المصدر |
32
+ |---|---|
33
+ | وسم `<script>` من CDN | `https://cdn.jsdelivr.net/npm/remote-webview-debugger@0.1.0/dist/sdk.js` أو `https://unpkg.com/remote-webview-debugger@0.1.0/dist/sdk.js` (IIFE مصغَّر، والمتغير العام `RemoteWebviewDebugger`؛ ثبّت رقم الإصدار، وأضف `integrity` إن شئت) |
34
+ | أداة تجميع (bundler) | `npm install remote-webview-debugger`، ثم `import { run, status } from 'remote-webview-debugger'` (وحدة ES مع الأنواع). استورده قبل شيفرتك ليبدأ الالتقاط مبكرًا. ولا تحمّل معه نسخة `<script>` في الصفحة نفسها |
35
+ | بوابتك | `https://<gateway>/v1/sdk.js`، وهي النسخة المضمَّنة في البوابة (ومتاحة أيضًا على عنوان معنون بالمحتوى لـ SRI تقترحه لوحة التحكم) |
36
+ | تطبيق أصلي | ضمّن `dist/sdk.js` من الحزمة في التطبيق، أو نزّله من أحد المصادر أعلاه؛ انظر [التكامل مع التطبيقات الأصلية](../docs/native-integration.ar.md) |
37
+
38
+ ## API
39
+
40
+ | API | الوصف |
41
+ |---|---|
42
+ | `run(gatewayUrl, appKey, opts?)` | يُدخل الصفحة إلى الاتصال (رمز الجهاز، الشارة). يعيد `Promise<{deviceCode, status}>`؛ واستدعاؤه مرة أخرى لا يضر. الخيارات أدناه. |
43
+ | `status()` | `{deviceCode, status, control, help, label, deviceId, pageId, version, lang, deviceToken, level, config, pending, logSession}`؛ قيمة `status` واحدة من `idle / connecting / online / polling / stopped / rejected / quota`، و `lang` لغة الواجهة (`null` قبل `run()`)، و `logSession` سجل الجلسة الذي تكتب فيه هذه الصفحة (`null` حين لا يجري التسجيل) |
44
+ | `stop()` | يقطع الاتصال ويزيل الواجهة (يستمر جمع console والشبكة، ضمن حدود) |
45
+ | `setUser(userId)` | يغيّر المستخدم؛ ويعيد الاتصال مرة واحدة برسالة `hello` جديدة |
46
+ | `help(on)` | طلب المساعدة / إلغاء الطلب |
47
+ | `nativeControl(nativeKey, action)` | تولّي التحكم / إعادة التحكم / الإنهاء من واجهة المضيف الأصلي نفسه |
48
+ | `nativeDecide(nativeKey, requestId, value)` | مع `nativeApproval`، يجيب عن `status().pending`: مستوى أو `null` لطلب الربط، و `'allow'` أو `null` لتأكيد إجراء حساس |
49
+ | `setLang(lang?)` | يبدّل لغة الواجهة أثناء التشغيل (إعداد اللغة الخاص بالتطبيق)؛ ودون وسيط يعود إلى لغات المتصفح. انظر [اللغات](#اللغات) |
50
+ | `registerLocale(pack)` | يضيف حزمة لغة، أو يستبدل حزمة لها `id` نفسه (ويقبل مصفوفة أيضًا). انظر [اللغات](#اللغات) |
51
+ | `builtinLocales` | معرّفات الحزم المضمَّنة |
52
+
53
+ خيارات `run()`:
54
+
55
+ | الخيار | الوصف |
56
+ |---|---|
57
+ | `userId` | المستخدم المسجَّل دخوله، ويُرسل مع `hello` |
58
+ | `deviceId` | معرّف جهاز ثابت يمرّره المضيف الأصلي (وإلا يُحفظ معرّف في localStorage) |
59
+ | `helpButton` | يُظهر زر «طلب المساعدة» (ويُدمج بعملية OR مع سياسة المشروع) |
60
+ | `app` | `{ name, version }` للتطبيق المضيف |
61
+ | `lang` | لغة كل ما يراه مستخدم الهاتف (الشارة، النافذة العائمة، الشريط السفلي، مربعات الحوار، الإشعارات العابرة، تبويب eruda، ووصف "AI wants to …" للإجراء الحساس): وسم لغة مثل `'ja'` أو `'pt-BR'`. الافتراضي: لغات المتصفح. انظر [اللغات](#اللغات) |
62
+ | `locales` | حزم لغات إضافية، تُسجَّل قبل اختيار اللغة (مثل `registerLocale`) |
63
+ | `messages` | نصوص بديلة لكل لغة: `{ en: { ui: { help: 'Contact support' } }, ar: { ui: { help: 'تواصل مع الدعم' } } }` |
64
+ | `networkExclude` | طلبات لا ينبغي أن يخوض فيها الوكيل — خطوط تُرجع 404 دائمًا، ومنارات التحليلات: `['.ttf', 'WebTracks', '*beacon*', '/\\/track\\//']`. تطابق كل قاعدة عنوان URL كسلسلة فرعية دون مراعاة حالة الأحرف، أو كنمط بمحرف البدل `*`، أو كتعبير نمطي حين تُكتب `/…/`. تُضاف إلى قواعد سياسة المشروع. تبقى الطلبات المطابقة خارج قائمة الشبكة وخارج أحداث الخط الزمني `net_fail`؛ لكن الصفحة تظل تسجّلها، فيستطيع الوكيل طلبها عبر `includeExcluded` |
65
+ | `lockScreen` | `false`: لا تُقفل الصفحة أثناء ربط وكيل بها (ويظل بإمكان المستخدم تغيير ذلك من النافذة العائمة). الافتراضي `true` |
66
+ | `theme` | `'auto'` (الافتراضي، يتبع خلفية الصفحة)، أو `'system'` أو `'light'` أو `'dark'` |
67
+ | `style` | ألوان الواجهة وخطوطها وأنصاف أقطار زواياها و z-index ومواضعها: `{ accent: '#e11d48', radius: 12, zIndex: 1000, pill: { side: 'left' } }`. انظر [التنسيق](#التنسيق) |
68
+ | `eruda` | `true` أو `{ dock, load, src, name }`: يعرض Remote Debugger كتبويب داخل eruda؛ ويحمّل `load` أحدث إصدار من eruda إن لم يكن في الصفحة. معطَّل افتراضيًا؛ ويمكن لسياسة المشروع تفعيله عن بُعد، والخيارات المحلية لها الأولوية حقلًا بحقل |
69
+ | `record` | `false`: لا تكتب هذه الصفحة أي سجل جلسة (ولا يُحذف شيء مخزَّن مسبقًا). الافتراضي `true`؛ ويمكن لسياسة المشروع إيقاف السجل لكل الصفحات |
70
+ | `launchId` | أيّ تشغيل للتطبيق تنتمي إليه هذه الصفحة، كي تحفظ كل WebView في عملية التطبيق الواحدة سجلّ جلستها تحت جلسة واحدة. يمرّر المضيف الأصلي معرّفه الخاص هنا (أو يعرّف `window.RWDLaunchId` كسلسلة نصية أو كدالة تعيدها)؛ وإلا يستنتج SDK التشغيل من ملف تعريف ارتباط للجلسة مع نبضة دورية |
71
+ | `nativeKey`، `deviceToken`، `nativeApproval` | للمضيفين الأصليين: السرّ الخاص بـ `nativeControl` / `nativeDecide`، وتوكن الجهاز الذي يحتفظ به المضيف، وطرح أسئلة الربط / التأكيد بواجهة أصلية |
72
+
73
+ ## اللغات
74
+
75
+ المضمَّنة: الإنجليزية (`en`)، والصينية المبسطة (`zh`)، والصينية التقليدية (`zh-TW`، وتُستخدم أيضًا لـ `zh-HK` و `zh-MO` و `zh-Hant`)، والفرنسية (`fr`)، والإسبانية (`es`)، والروسية (`ru`)، والعربية (`ar`، بتخطيط من اليمين إلى اليسار)، واليابانية (`ja`)، والكورية (`ko`)، والألمانية (`de`)، والبرتغالية (`pt`، البرازيلية؛ وتُستخدم أيضًا لـ `pt-PT`).
76
+
77
+ **اختيار اللغة.** لغة مستخدم الهاتف هي `run({ lang })` إن مُرِّرت، ثم كل وسم في `navigator.languages` بالترتيب. لكل وسم يجرّب SDK الوسم نفسه ثم صيغه الأقصر (`pt-BR` → `pt`، `zh-HK` → `zh-TW` → `zh`)، ويأخذ أول لغة لديه حزمة لها، ويعود إلى الإنجليزية إن لم يجد. والنصوص الناقصة من حزمة ما تعود بالطريقة نفسها، فلا بأس بحزمة جزئية. يبدّل `setLang('ja')` اللغة أثناء التشغيل؛ و `status().lang` هي الحزمة المستخدمة.
78
+
79
+ **التحميل.** الإنجليزية والصينية المبسطة مضمَّنتان في `sdk.js`. أما بقية الحزم فتُحمَّل عند الحاجة، في أول مرة تحتاجها الصفحة (وتعرض الواجهة لغة الاحتياط في تلك اللحظة):
80
+
81
+ - نسخة `<script>`: من `locales/<id>.js` بجوار `sdk.js` (مسار CDN، مثل `…/remote-webview-debugger@0.1.0/dist/locales/ja.js`، أو `/v1/locales/ja.js` على بوابتك)، ومن البوابة الممرَّرة إلى `run()` إن فشل ذلك. ولتجنّب الطلب الإضافي، حمّل الحزمة بنفسك، قبل `sdk.js` أو بعده: `<script src="…/dist/locales/ja.js"></script>`.
82
+ - نسخة وحدة ES: استيراد ديناميكي، فتضع أداة التجميع كل لغة في جزء (chunk) مستقل. ولتجميع إحداها مسبقًا بدلًا من ذلك: `import ja from 'remote-webview-debugger/locales/ja'`، ثم `run(url, key, { locales: [ja] })`.
83
+
84
+ **حزمك ونصوصك الخاصة.** الحزمة هي `{ id, name, dir?, ui?, action?, agent? }`؛ وكل ما يُترك منها يُؤخذ من لغات الاحتياط الخاصة بها:
85
+
86
+ <div dir="ltr">
87
+
88
+ ```js
89
+ RemoteWebviewDebugger.registerLocale({
90
+ id: 'it',
91
+ name: 'Italiano',
92
+ ui: { takeover: 'Prendi il controllo', end: 'Termina', help: 'Richiedi assistenza' /* … */ },
93
+ })
94
+ RemoteWebviewDebugger.run(url, key, {
95
+ messages: { ar: { ui: { help: 'تواصل مع الدعم' } } }, // تغيير نصوص مفردة في أي لغة
96
+ })
97
+ ```
98
+
99
+ </div>
100
+
101
+ `ui` هي نصوص الواجهة، و `action` تُكمل عبارة "AI wants to …" في مربع حوار التأكيد، و `agent` هي ما يعود إلى الوكيل. تسرد أنواع TypeScript (`LocalePack`، `Messages`، `UiMessages`، `ActionMessages`، `AgentMessages`) كل المفاتيح؛ والمرجع هو `src/locales/en.ts`.
102
+
103
+ **جمهوران.** يحصل مستخدم الهاتف على اللغة المذكورة أعلاه. أما الوكيل فيقرأ رسائل أخطاء RPC وملخصات الخط الزمني (النقرات، التنقل داخل الصفحة، الطلبات الفاشلة) بلغة البوابة، `welcome.agentLang` (`RWD_LANG`)، وتُحمَّل حزمتها بالطريقة نفسها. تكون بالإنجليزية إلى أن تقول رسالة welcome غير ذلك؛ وتُحفظ آخر قيمة في localStorage `rwd:alang`، فتستخدمها كذلك الأحداث التي تسبق رسالة welcome للصفحة التالية.
104
+
105
+ وهكذا يمكن لمستخدم يتحدث الصينية أن يعمل مع وكيل يتحدث الإنجليزية: يسأل مربع الحوار `AI 想要点击「提交订单」,允许吗?`، وإن رُفض يقرأ الوكيل `The user denied this action`.
106
+
107
+ ## التنسيق
108
+
109
+ تعيش الواجهة في جذر ظلّ (shadow root) على `#__rwd` (خارج `<body>`)، فلا تصل إليها أنماط CSS الخاصة بالصفحة إلا عبر هذه المنافذ:
110
+
111
+ - **خصائص CSS المخصّصة** على `:root` أو `#__rwd`، مثل `:root { --rwd-accent-rgb: 225, 29, 72; --rwd-radius: 12px; }`.
112
+ - **`run({ style })`**، الذي يضبط الخصائص نفسها على `#__rwd`. وتقبل الألوان هنا أي لون CSS.
113
+ - **`::part()`** لأي شيء آخر: `#__rwd::part(bar) { … }`. الأجزاء: `pill`، `window`، `bar`، `task`، `dialog`، `toast`، `button`، `cursor`، `glow`، `overlay`. أسماء الأصناف (class) في الداخل ليست واجهة API مستقرة.
114
+ - **`theme`**: زجاج فاتح أو داكن (الافتراضي: يتبع خلفية الصفحة).
115
+
116
+ | الخاصية | حقل `style` | الافتراضي | ماذا |
117
+ |---|---|---|---|
118
+ | `--rwd-accent-rgb` | `accent` | `59, 130, 246` | الأزرار، والمفاتيح، ومؤشر الوكيل، والإبرازات، والتوهّج على الحواف |
119
+ | `--rwd-danger-rgb` | `danger` | `239, 68, 68` | زر «إنهاء» |
120
+ | `--rwd-warning-rgb` | `warning` | `245, 158, 11` | «طلب المساعدة» و«قيد المساعدة»؛ وحالة تحكّم المستخدم |
121
+ | `--rwd-success-rgb` | `success` | `34, 197, 94` | نقطة الاتصال؛ و«تم النسخ» |
122
+ | `--rwd-font` | `font` | خط واجهة النظام (بحسب اللغة للصينية واليابانية والكورية) | كل النصوص |
123
+ | `--rwd-font-mono` | `monoFont` | `ui-monospace, "SF Mono", …` | رمز الجهاز والوسوم |
124
+ | `--rwd-radius` | `radius` | `18px` | النافذة العائمة؛ ومربع الحوار أكثر استدارة بـ 2px، وبطاقة المهمة والشارة أقل بـ 2px، وأزرار مربع الحوار أقل بـ 6px |
125
+ | `--rwd-button-radius` | `buttonRadius` | `999px` | الأزرار، والشريط السفلي، والإشعارات العابرة |
126
+ | `--rwd-z-index` | `zIndex` | `2147483647` | الواجهة كلها |
127
+ | `--rwd-bar-bottom` | `barBottom` | `14px` | الشريط السفلي، فوق المنطقة الآمنة السفلية |
128
+ | `--rwd-task-top` | `taskTop` | `10px` | بطاقة المهمة، تحت المنطقة الآمنة العلوية |
129
+ | `--rwd-toast-bottom` | `toastBottom` | `84px` | الإشعارات العابرة، فوق المنطقة الآمنة السفلية |
130
+ | — | `pill: { side, top }` | الحافة اليمنى (اليسرى في اللغات المكتوبة من اليمين إلى اليسار)، `0.62` | موضع بدء الشارة الخاملة إلى أن يسحبها المستخدم؛ و `top` من 0 (الأعلى) إلى 1 (الأسفل) |
131
+
132
+ الألوان ثلاثيات `r, g, b` كي تتبعها الظلال شبه الشفافة (على نهج `--bs-*-rgb` في Bootstrap).
133
+
134
+ ## السلوك داخل الصفحة (البروتوكول §6–§8، §11)
135
+
136
+ - المستويات: تُفحص استدعاءات RPC مقابل `welcome.level` / `control.level` (`forbidden`، "Requires the … level"). الوكيل الذي بلا مستوى (من بوابة أقدم) يحصل على `interact`؛ وحين لا يكون أي وكيل مرتبطًا لا يُفرض شيء إضافي.
137
+ - يُحفظ توكن الجهاز في localStorage `rwd:dtoken`، وتوكن الاستئناف في sessionStorage `rwd:resume` (مقيَّدًا بـ pageId). رمز الإغلاق 4401: إن كان التوكن قد تغيّر في الأثناء (تبويب آخر للجهاز حصل عليه للتو)، يُعاد المحاولة فورًا مرة واحدة، وإلا `rejected` وإعادة المحاولة بعد نحو 10 دقائق؛ 4409: إعادة الاتصال بـ pageId جديد؛ 4429: `quota`، وإعادة المحاولة بعد نحو 5 دقائق.
138
+ - يُنتزع `rwd_invite` من شريط العنوان عند `run()` (`history.replaceState`) ويُرسل مع hello إلى أن تصل رسالة welcome.
139
+ - `welcome.config`: `helpButton` (بعملية OR مع خيار `run()`)، و `maskSelectors`، و `maskPatterns` (اللقطة، console، عناوين URL للشبكة، قيم التخزين، ملخصات الخط الزمني)، و `confirmSelectors`، و `networkExclude` (تُضاف إلى قواعد خيار `run()`)، و `sessionLog`. يُحفظ آخر إعداد في localStorage `rwd:cfg` ويُستخدم إلى أن تصل رسالة welcome — فالمشروع الذي أوقف سجل الجلسة يبقيه موقوفًا منذ اللحظة الأولى للصفحة التالية، قبل أي welcome.
140
+ - تنتهي اللقطات بقسم `[Overlays]` يسرد ما يطفو فوق الصفحة — الخلفية المعتمة لنافذة منبثقة، أو نافذة مشروطة (modal)، أو لوحة سفلية — مع وسمها، ومقطع نصي قصير، والنسبة التي تغطيها من منفذ العرض، ومرجع ref. الخلفية المعتمة عنصر فارغ لا عقدة له في لقطة aria، لذا تحصل على مرجع `oN` بدلًا من `eN`؛ وهذا ما يتيح للوكيل النقر عليها لإغلاق النافذة المنبثقة.
141
+ - تستهدف النقرة أولًا المركز المرئي للعنصر، ثم النقاط الأخرى من شبكة 3×3 داخله، فلا تحجب شارةٌ فوق زرٍّ ذلك الزر. وحين تكون كل النقاط مغطاة، يفشل RPC بـ `not_interactable` ويسمّي العنصر الحاجب ومرجعه.
142
+ - مربعا حوار الربط والإجراء الحساس (`[data-rwd-confirm]`، و `confirmSelectors`، بما في ذلك إرسال نموذج بمفتاح Enter) يعيشان في Shadow DOM، ولا يقبلان إلا النقرات الموثوقة، ولا يصبحان فعّالين إلا بعد 0.4 ثانية من ظهورهما. تتشارك التبويبات من الأصل (origin) نفسه طلبات الربط التي حُسمت عبر BroadcastChannel.
143
+
144
+ يبدأ تحميل الملف بجمع console والأخطاء غير الملتقطة والشبكة (XHR، fetch، WebSocket، sendBeacon، EventSource)، بحد أقصى 500 مدخل لكلٍّ منها؛ وعند الامتلاء تُحذف السجلات العادية والطلبات الناجحة أولًا. تُخزَّن أجسام الاستجابات مؤقتًا حتى 5 MB إجمالًا، و 64 KB لكلٍّ منها. لذا حمّله بشكل متزامن ومبكرًا في `<head>`.
145
+
146
+ ## سجل الجلسة (البروتوكول §5.4)
147
+
148
+ تلك المخازن المؤقتة هي ذاكرة صفحة واحدة. وبالتوازي يكتب SDK **سجل جلسة** في IndexedDB (`rwd-log`) على الجهاز، كي يتمكّن الوكيل الذي يرتبط بعد وقوع خلل من قراءة كل ما أدى إليه:
149
+
150
+ - الجلسة الواحدة هي تشغيل واحد للتطبيق، تتشاركه كل صفحات الأصل (origin): `run({ launchId })`، وإلا `window.RWDLaunchId`، وإلا يُستنتج من ملف تعريف ارتباط الجلسة `rwd_launch` مع نبضة دورية (جلسة ملف تعريف ارتباط صامتة لأكثر من ساعة تُعدّ تشغيلًا جديدًا). `status().logSession` هو المعرّف المستخدم.
151
+ - ما يُسجَّل: فتح الصفحة / التنقل داخلها / الانتقال بين المقدمة والخلفية / المغادرة، ونقرات المستخدم وإدخاله وعمليات الإرسال ومواضع استقرار التمرير، واستدعاءات الوكيل التفاعلية و `rwd.evaluate`، وتغييرات حالة التحكم، و console بكل مستوياته، وكل طلب مكتمل — والفاشلة منها مع ترويساتها وأجسامها بعد التنقيح (64 KB لكلٍّ منها). يعمل سواء أمكن الوصول إلى البوابة أم لا. تُخزَّن الحقول المخفاة بصورة `••••`، وتُطبَّق `maskPatterns` لحظة كتابة السجلات.
152
+ - ما يُحتفظ به: آخر 3 تشغيلات، 10 MB لكلٍّ منها؛ وما زاد عن ذلك تُحذف منه السجلات العادية والطلبات الناجحة أولًا. التشغيل الحالي فقط حين تكون حصة التخزين دون 64 MB؛ ولا شيء على الإطلاق في غياب IndexedDB.
153
+ - يقرؤه الوكيل عبر `rwd.log` (`observe`) و `rwd.logDetail` (`advanced`، للترويسات والأجسام). ولا يغادر الجهازَ شيءٌ منه بخلاف ذلك.
154
+ - يُوقَف بـ `run({ record: false })` لصفحة واحدة، أو بـ `policy.sessionLog: false` للمشروع — وهذا يحذف أيضًا ما خزّنه هذا الأصل مسبقًا.
155
+
156
+ ## بنية الشيفرة
157
+
158
+ - `src/index.ts`: الواجهة العامة، والجلسة، وتوزيع RPC، وحالة التحكم.
159
+ - `src/transport.ts`: اتصال WebSocket للصفحة (بالمُنشئ الأصلي)، ومهلة النبضة، والتراجع الأسّي، وبعد 3 محاولات فاشلة `POST /v1/presence` كل 60 ثانية.
160
+ - `src/ids.ts`: deviceId / pageId / openerId.
161
+ - `src/launch.ts`: أيّ تشغيل للتطبيق تنتمي إليه هذه الصفحة (`launchId`، `window.RWDLaunchId`، ملف تعريف الارتباط `rwd_launch`).
162
+ - `src/pageWatch.ts`: رسائل `page` (url، title، visibility) وأحداث الخط الزمني (التنقل داخل الصفحة، نقرات المستخدم).
163
+ - `src/ui.ts`، `src/lock.ts`: الشارة، وزر «طلب المساعدة»، وطبقة القفل، والتوهّج، وإبراز الإجراء، ومربعات الحوار في Shadow DOM؛ يحجب إدخال المستخدم الموثوق أثناء ربط وكيل، ويعرض منذ متى هو متصل.
164
+ - `src/approval.ts`: الموافقة على الربط وتأكيد الإجراء الحساس (مربع حوار في الصفحة، أو المضيف الأصلي عبر `nativeDecide`).
165
+ - `src/i18n.ts`، `src/locales/`، `src/localeLoader*.ts`: حزم اللغات (نصوص الواجهة والإجراءات والوكيل لكل لغة)، والاختيار والاحتياط، والتحميل عند الحاجة؛ ويبني `scripts/locales.mjs` الملفات `dist/locales/<id>.js`.
166
+ - يعيش محرّك الوكيل بجوار chobitsu في `packages/chobitsu/src/engine/rwd/`: اللقطة، و `rwd.query`، وفحوص قابلية التنفيذ، والإدخال المُصطنَع، ولوحة المفاتيح، ومخازن console / الشبكة المؤقتة، ولقطات الشاشة، و `rwd.storage`، وسجل الجلسة في IndexedDB (`coldlog.ts`)، وكشف الطبقات العائمة (`overlays.ts`)، والمستويات وقواعد التأكيد (`policy.ts`)، والنصوص الموجّهة إلى الوكيل (`i18n.ts`). مصادر Playwright المستخدمة في اللقطات موجودة في `packages/chobitsu/src/engine/vendor/playwright/`. ويجمّعها البناء من المصدر في `dist/sdk.js`.
167
+
168
+ ## البناء والاختبار
169
+
170
+ <div dir="ltr">
171
+
172
+ ```sh
173
+ cd sdk
174
+ npm ci
175
+ npm run build # dist/sdk.js (IIFE، المتغير العام RemoteWebviewDebugger، ES2017)، dist/index.mjs + index.d.ts (وحدة ES)
176
+ npm run typecheck
177
+ npm test # Playwright: WebKit (iPhone 15) + Chromium (Pixel 7)
178
+ npm run gateway # بوابة وهمية محلية: http://localhost:8787/demo/platform/?key=rwd_pk_demo
179
+ ```
180
+
181
+ </div>
182
+
183
+ تستخدم الاختبارات `test/mock-gateway.mjs`، الذي ينفّذ جانب الصفحة من البروتوكول (welcome، حالة التحكم، استدعاءات RPC، presence؛ التوكنات، رموز الإغلاق، المستويات، الإعداد عن بُعد، `agentLang`، الموافقة على الربط) ويقدّم `/v1/sdk.js`، وحزم اللغات تحت `/v1/locales/`، والمتجر التجريبي. وهو لا يتحقق من المستويات بنفسه، فتختبر الاختبارات الإنفاذ الذي تقوم به الصفحة ذاتها. تعمل المواصفات في `test/e2e/` بمتصفح `zh-CN` و `agentLang: 'zh'` ما لم يقل الاختبار غير ذلك؛ ويغطي `i18n.spec.ts` الإنجليزية، و `locales.spec.ts` بقية حزم اللغات، والاحتياط، والحزم المخصّصة، والتنسيق، والتخطيط من اليمين إلى اليسار. يحمّل اختبار التعايش eruda 3.4.3 و PageSpy 2.4.0 من jsdelivr، لذا يحتاج إلى اتصال بالإنترنت.
184
+
185
+ </div>
package/README.de.md ADDED
@@ -0,0 +1,169 @@
1
+ <!-- i18n-source: d9a31993ea867d3ef7058e7d637886f38a6ee3e1 -->
2
+ [English](README.md) | [简体中文](README.zh-CN.md) | [繁體中文](README.zh-TW.md) | [日本語](README.ja.md) | [한국어](README.ko.md) | [Español](README.es.md) | [Français](README.fr.md) | Deutsch | [Português (Brasil)](README.pt-BR.md) | [Русский](README.ru.md) | [العربية](README.ar.md)
3
+
4
+ # RWD-Seiten-SDK (`sdk/`)
5
+
6
+ Eine JS-Datei, die eine App-WebView oder H5-Seite lädt, damit ein KI-Agent die Seite über das RWD-Gateway (`gateway/`) und MCP untersuchen und bedienen kann. Protokoll: [`docs/protocol.de.md`](../docs/protocol.de.md); Architektur: [`docs/architecture.de.md`](../docs/architecture.de.md).
7
+
8
+ ```html
9
+ <script src="https://cdn.jsdelivr.net/npm/remote-webview-debugger@0.1.0/dist/sdk.js"></script>
10
+ <script>
11
+ RemoteWebviewDebugger.run("https://rwd.example.com/v1", "rwd_pk_xxxxxxxx", {
12
+ userId: "u-42", // optional
13
+ deviceId: "…", // optional; von einem nativen Host übergeben, der das SDK injiziert
14
+ helpButton: true, // optional; zeigt den Button "Unterstützung anfordern"
15
+ app: { name: "Shop", version: "3.2.0" },
16
+ lang: "en", // optional; ein Sprach-Tag, standardmäßig aus den Browsersprachen
17
+ }).then(({ deviceCode, status }) => console.log(deviceCode, status))
18
+ </script>
19
+ ```
20
+
21
+ ## SDK beziehen
22
+
23
+ Auf npm veröffentlicht als [`remote-webview-debugger`](https://www.npmjs.com/package/remote-webview-debugger); Versionen und Änderungen: [CHANGELOG](CHANGELOG.md).
24
+
25
+ | Verwendung | Quelle |
26
+ |---|---|
27
+ | `<script>` von einem CDN | `https://cdn.jsdelivr.net/npm/remote-webview-debugger@0.1.0/dist/sdk.js` oder `https://unpkg.com/remote-webview-debugger@0.1.0/dist/sdk.js` (minifizierte IIFE, globales `RemoteWebviewDebugger`; pinnen Sie die Version und ergänzen Sie bei Bedarf `integrity`) |
28
+ | Ein Bundler | `npm install remote-webview-debugger`, dann `import { run, status } from 'remote-webview-debugger'` (ES-Modul mit Typen). Importieren Sie es vor Ihrem eigenen Code, damit die Erfassung früh beginnt. Laden Sie auf derselben Seite nicht zusätzlich die `<script>`-Variante |
29
+ | Ihr Gateway | `https://<gateway>/v1/sdk.js`, die im Gateway eingebettete Kopie (auch unter einer inhaltsadressierten URL für SRI, die die Konsole anbietet) |
30
+ | Eine native App | `dist/sdk.js` aus dem Paket mitliefern oder von einer der obigen Quellen herunterladen; siehe [native Integration](../docs/native-integration.de.md) |
31
+
32
+ ## API
33
+
34
+ | API | Beschreibung |
35
+ |---|---|
36
+ | `run(gatewayUrl, appKey, opts?)` | Bringt die Seite online (Gerätecode, Badge). Gibt `Promise<{deviceCode, status}>` zurück; ein erneuter Aufruf schadet nicht. Optionen siehe unten. |
37
+ | `status()` | `{deviceCode, status, control, help, label, deviceId, pageId, version, lang, deviceToken, level, config, pending, logSession}`; `status` ist `idle / connecting / online / polling / stopped / rejected / quota`, `lang` die UI-Sprache (`null` vor `run()`), `logSession` das Sitzungsprotokoll, in das diese Seite schreibt (`null`, wenn nicht aufgezeichnet wird) |
38
+ | `stop()` | Trennt die Verbindung und entfernt die UI (die Erfassung von Console und Netzwerk läuft begrenzt weiter) |
39
+ | `setUser(userId)` | Wechselt den Nutzer; verbindet sich einmal mit einem neuen `hello` neu |
40
+ | `help(on)` | Unterstützung anfordern / Anfrage abbrechen |
41
+ | `nativeControl(nativeKey, action)` | Übernehmen / Zurückgeben / Beenden aus der eigenen UI des nativen Hosts |
42
+ | `nativeDecide(nativeKey, requestId, value)` | Beantwortet mit `nativeApproval` die Frage in `status().pending`: eine Stufe oder `null` bei einer Zugriffsanfrage, `'allow'` oder `null` bei der Bestätigung einer sensiblen Aktion |
43
+ | `setLang(lang?)` | Wechselt die UI-Sprache zur Laufzeit (die eigene Spracheinstellung einer App); ohne Argument gelten wieder die Browsersprachen. Siehe [Sprachen](#sprachen) |
44
+ | `registerLocale(pack)` | Fügt ein Sprachpaket hinzu oder ersetzt eines mit derselben `id` (nimmt auch ein Array). Siehe [Sprachen](#sprachen) |
45
+ | `builtinLocales` | Die ids der eingebauten Pakete |
46
+
47
+ Optionen von `run()`:
48
+
49
+ | Option | Beschreibung |
50
+ |---|---|
51
+ | `userId` | Der angemeldete Nutzer, wird mit dem `hello` gesendet |
52
+ | `deviceId` | Eine stabile Geräte-ID von einem nativen Host (sonst wird eine in localStorage gespeichert) |
53
+ | `helpButton` | Zeigt den Button „Unterstützung anfordern“ (ODER-verknüpft mit der Projektrichtlinie) |
54
+ | `app` | `{ name, version }` der Host-App |
55
+ | `lang` | Sprache von allem, was der Nutzer auf dem Telefon sieht (Badge, schwebendes Fenster, untere Leiste, Dialoge, Toasts, der eruda-Tab und die Beschreibung „Die KI möchte …“ einer sensiblen Aktion): ein Sprach-Tag wie `'ja'` oder `'pt-BR'`. Standard: die Browsersprachen. Siehe [Sprachen](#sprachen) |
56
+ | `locales` | Zusätzliche Sprachpakete, die vor der Sprachwahl registriert werden (wie `registerLocale`) |
57
+ | `messages` | Zu überschreibende Meldungen, pro Sprache: `{ en: { ui: { help: 'Contact support' } }, zh: { ui: { help: '联系客服' } } }` |
58
+ | `networkExclude` | Anfragen, durch die sich der Agent nicht wühlen soll – Schriften, die immer 404 liefern, Analytics-Beacons: `['.ttf', 'WebTracks', '*beacon*', '/\\/track\\//']`. Jede Regel trifft die URL als Teilstring ohne Beachtung der Groß-/Kleinschreibung, als Muster mit `*`-Platzhalter oder, wenn als `/…/` geschrieben, als regulärer Ausdruck. Wird zu den Regeln der Projektrichtlinie hinzugefügt. Passende Anfragen tauchen weder in der Netzwerkliste noch in `net_fail`-Ereignissen der Zeitleiste auf; die Seite zeichnet sie trotzdem auf, sodass ein Agent sie mit `includeExcluded` abfragen kann |
59
+ | `lockScreen` | `false`: die Seite nicht sperren, solange ein Agent verbunden ist (der Nutzer kann das im schwebenden Fenster trotzdem ändern). Standard `true` |
60
+ | `theme` | `'auto'` (Standard, folgt dem Seitenhintergrund), `'system'`, `'light'` oder `'dark'` |
61
+ | `style` | Farben, Schriften, Radien, z-index und Positionen der UI: `{ accent: '#e11d48', radius: 12, zIndex: 1000, pill: { side: 'left' } }`. Siehe [Styling](#styling) |
62
+ | `eruda` | `true` oder `{ dock, load, src, name }`: zeigt Remote Debugger als Tab in eruda; `load` lädt das neueste eruda, wenn die Seite keines hat. Standardmäßig aus; die Projektrichtlinie kann es aus der Ferne einschalten, lokale Optionen haben Feld für Feld Vorrang |
63
+ | `record` | `false`: diese Seite schreibt kein Sitzungsprotokoll (bereits Gespeichertes wird nicht gelöscht). Standard `true`; die Projektrichtlinie kann das Protokoll für alle Seiten abschalten |
64
+ | `launchId` | Zu welchem App-Start diese Seite gehört, damit jede WebView eines App-Prozesses ihr Sitzungsprotokoll unter einer Sitzung ablegt. Ein nativer Host übergibt hier seine eigene ID (oder definiert `window.RWDLaunchId` als String oder als Funktion, die einen liefert); andernfalls leitet das SDK den Start aus einem Sitzungscookie plus Heartbeat ab |
65
+ | `nativeKey`, `deviceToken`, `nativeApproval` | Für native Hosts: das Geheimnis für `nativeControl` / `nativeDecide`, das Geräte-Token, das der Host aufbewahrt, und die Rückfragen zu Verbindung / Bestätigung nativ stellen |
66
+
67
+ ## Sprachen
68
+
69
+ Eingebaut: Englisch (`en`), vereinfachtes Chinesisch (`zh`), traditionelles Chinesisch (`zh-TW`, auch für `zh-HK`, `zh-MO` und `zh-Hant`), Französisch (`fr`), Spanisch (`es`), Russisch (`ru`), Arabisch (`ar`, von rechts nach links), Japanisch (`ja`), Koreanisch (`ko`), Deutsch (`de`) und Portugiesisch (`pt`, brasilianisch; auch für `pt-PT`).
70
+
71
+ **Sprachwahl.** Die Sprache des Nutzers ist `run({ lang })`, falls angegeben, danach der Reihe nach jeder Eintrag von `navigator.languages`. Für jedes Tag probiert das SDK das Tag und dann kürzere Formen davon (`pt-BR` → `pt`, `zh-HK` → `zh-TW` → `zh`), nimmt die erste Sprache, für die es ein Paket hat, und fällt sonst auf Englisch zurück. Fehlende Meldungen eines Pakets fallen auf dieselbe Weise zurück, ein unvollständiges Paket ist also kein Problem. `setLang('ja')` wechselt zur Laufzeit; `status().lang` ist das verwendete Paket.
72
+
73
+ **Laden.** Englisch und vereinfachtes Chinesisch stecken in `sdk.js`. Die übrigen Pakete werden bei Bedarf nachgeladen, wenn eine Seite sie zum ersten Mal braucht (so lange zeigt die UI die Rückfallsprache):
74
+
75
+ - `<script>`-Build: aus `locales/<id>.js` neben `sdk.js` (der CDN-Pfad, z. B. `…/remote-webview-debugger@0.1.0/dist/locales/ja.js`, oder `/v1/locales/ja.js` Ihres Gateways), und falls das scheitert, vom an `run()` übergebenen Gateway. Um die zusätzliche Anfrage zu vermeiden, laden Sie das Paket selbst, vor oder nach `sdk.js`: `<script src="…/dist/locales/ja.js"></script>`.
76
+ - ES-Modul-Build: ein dynamischer Import, sodass Ihr Bundler jede Sprache in einen eigenen Chunk legt. Um eine Sprache stattdessen direkt mitzubündeln: `import ja from 'remote-webview-debugger/locales/ja'`, dann `run(url, key, { locales: [ja] })`.
77
+
78
+ **Eigene Pakete und Formulierungen.** Ein Paket ist `{ id, name, dir?, ui?, action?, agent? }`; alles Fehlende kommt aus seinen Rückfallsprachen:
79
+
80
+ ```js
81
+ RemoteWebviewDebugger.registerLocale({
82
+ id: 'it',
83
+ name: 'Italiano',
84
+ ui: { takeover: 'Prendi il controllo', end: 'Termina', help: 'Richiedi assistenza' /* … */ },
85
+ })
86
+ RemoteWebviewDebugger.run(url, key, {
87
+ messages: { en: { ui: { help: 'Contact support' } } }, // einzelne Meldungen beliebiger Sprachen ändern
88
+ })
89
+ ```
90
+
91
+ `ui` ist der UI-Text, `action` ergänzt „Die KI möchte …“ im Bestätigungsdialog, und `agent` ist das, was an den Agent zurückgeht. Die TypeScript-Typen (`LocalePack`, `Messages`, `UiMessages`, `ActionMessages`, `AgentMessages`) listen jeden Schlüssel auf; `src/locales/en.ts` ist die Referenz.
92
+
93
+ **Zwei Zielgruppen.** Der Nutzer auf dem Telefon bekommt die oben gewählte Sprache. Der Agent liest RPC-Fehlermeldungen und Zusammenfassungen der Zeitleiste (Taps, Navigation innerhalb der Seite, fehlgeschlagene Anfragen) in der Sprache des Gateways, `welcome.agentLang` (`RWD_LANG`), und dieses Paket wird auf dieselbe Weise geladen. Bis ein welcome etwas anderes sagt, gilt Englisch; der letzte Wert wird in localStorage `rwd:alang` gespeichert, sodass auch Ereignisse vor dem welcome der nächsten Seite ihn verwenden.
94
+
95
+ So kann ein chinesischsprachiger Nutzer mit einem englischsprachigen Agent arbeiten: Der Dialog fragt `AI 想要点击「提交订单」,允许吗?`, und bei Ablehnung liest der Agent `The user denied this action`.
96
+
97
+ ## Styling
98
+
99
+ Die UI lebt in einem Shadow Root an `#__rwd` (außerhalb von `<body>`), sodass Seiten-CSS sie nur über diese Einstiegspunkte erreicht:
100
+
101
+ - **CSS Custom Properties** auf `:root` oder `#__rwd`, z. B. `:root { --rwd-accent-rgb: 225, 29, 72; --rwd-radius: 12px; }`.
102
+ - **`run({ style })`**, das dieselben Properties auf `#__rwd` setzt. Farben dürfen dort beliebige CSS-Farben sein.
103
+ - **`::part()`** für alles andere: `#__rwd::part(bar) { … }`. Parts: `pill`, `window`, `bar`, `task`, `dialog`, `toast`, `button`, `cursor`, `glow`, `overlay`. Klassennamen darin sind keine stabile API.
104
+ - **`theme`**: helles oder dunkles Glas (Standard: folgt dem Seitenhintergrund).
105
+
106
+ | Property | `style`-Feld | Standard | Wofür |
107
+ |---|---|---|---|
108
+ | `--rwd-accent-rgb` | `accent` | `59, 130, 246` | Buttons, Schalter, der Zeiger des Agents, Hervorhebungen und das Leuchten am Rand |
109
+ | `--rwd-danger-rgb` | `danger` | `239, 68, 68` | Der Button „Beenden“ |
110
+ | `--rwd-warning-rgb` | `warning` | `245, 158, 11` | „Unterstützung anfordern“ und „In Betreuung“; der Zustand, in dem der Nutzer steuert |
111
+ | `--rwd-success-rgb` | `success` | `34, 197, 94` | Online-Punkt; „Kopiert“ |
112
+ | `--rwd-font` | `font` | System-UI-Schrift (für Chinesisch, Japanisch, Koreanisch je Sprache) | Aller Text |
113
+ | `--rwd-font-mono` | `monoFont` | `ui-monospace, "SF Mono", …` | Gerätecode und Tags |
114
+ | `--rwd-radius` | `radius` | `18px` | Schwebendes Fenster; der Dialog ist 2px runder, Aufgabenkarte und Badge 2px weniger, Dialog-Buttons 6px weniger |
115
+ | `--rwd-button-radius` | `buttonRadius` | `999px` | Buttons, die untere Leiste und Toasts |
116
+ | `--rwd-z-index` | `zIndex` | `2147483647` | Die gesamte UI |
117
+ | `--rwd-bar-bottom` | `barBottom` | `14px` | Untere Leiste, oberhalb des unteren Safe-Area-Bereichs |
118
+ | `--rwd-task-top` | `taskTop` | `10px` | Aufgabenkarte, unterhalb des oberen Safe-Area-Bereichs |
119
+ | `--rwd-toast-bottom` | `toastBottom` | `84px` | Toasts, oberhalb des unteren Safe-Area-Bereichs |
120
+ | — | `pill: { side, top }` | rechter Rand (links bei Sprachen, die von rechts nach links laufen), `0.62` | Wo das Badge im Ruhezustand beginnt, bis der Nutzer es verschiebt; `top` von 0 (oben) bis 1 (unten) |
121
+
122
+ Farben sind `r, g, b`-Tripel, damit die durchscheinenden Abstufungen mitgehen (dieselbe Konvention wie Bootstraps `--bs-*-rgb`).
123
+
124
+ ## Verhalten in der Seite (Protokoll §6–§8, §11)
125
+
126
+ - Stufen: RPCs werden gegen `welcome.level` / `control.level` geprüft (`forbidden`, „Erfordert die Zugriffsstufe …“). Ein Agent ohne Stufe (ein älteres Gateway) bekommt `interact`; ohne verbundenen Agent wird nichts zusätzlich erzwungen.
127
+ - Das Geräte-Token liegt in localStorage `rwd:dtoken`, das Resume-Token in sessionStorage `rwd:resume` (an die pageId gebunden). Close-Code 4401: Hat sich das Token inzwischen geändert (ein anderer Tab des Geräts hat es gerade bekommen), sofort einmal erneut versuchen, sonst `rejected` und nach etwa 10 Minuten erneut versuchen; 4409: mit einer neuen pageId neu verbinden; 4429: `quota`, nach etwa 5 Minuten erneut versuchen.
128
+ - `rwd_invite` in der Adresszeile wird bei `run()` entfernt (`history.replaceState`) und mit dem hello gesendet, bis ein welcome eintrifft.
129
+ - `welcome.config`: `helpButton` (ODER-verknüpft mit der `run()`-Option), `maskSelectors`, `maskPatterns` (Snapshot, Console, Netzwerk-URLs, Storage-Werte, Zusammenfassungen der Zeitleiste), `confirmSelectors`, `networkExclude` (zu den Regeln der `run()`-Option hinzugefügt), `sessionLog`. Die letzte Konfiguration wird in localStorage `rwd:cfg` gespeichert und verwendet, bis das welcome eintrifft – ein Projekt, das das Sitzungsprotokoll abgeschaltet hat, hält es also schon ab dem ersten Moment der nächsten Seite aus, noch vor jedem welcome.
130
+ - Snapshots enden mit einem Abschnitt `[Overlays]`, der auflistet, was über der Seite schwebt – der Hintergrund eines Popups, ein Modal, ein Bottom Sheet –, jeweils mit Tag, einem kurzen Textausschnitt, dem Anteil des Viewports, den es bedeckt, und einer ref. Ein Hintergrund ist ein leeres Element, für das der ARIA-Snapshot keinen Knoten hat; er bekommt deshalb eine `oN`-ref statt `eN`. Genau dadurch kann ein Agent ihn antippen, um das Popup zu schließen.
131
+ - Ein Klick zielt zuerst auf die sichtbare Mitte des Elements, dann auf die übrigen Punkte eines 3×3-Rasters darin, sodass ein Badge über einem Button ihn nicht blockiert. Sind alle Punkte verdeckt, schlägt der RPC mit `not_interactable` fehl und nennt das verdeckende Element und seine ref.
132
+ - Die Dialoge für Verbindung und sensible Aktionen (`[data-rwd-confirm]`, `confirmSelectors`, einschließlich Enter, das ein Formular absendet) leben in einem Shadow DOM, nehmen nur vertrauenswürdige Taps an und werden 0,4 s nach dem Erscheinen scharf geschaltet. Tabs desselben Origins teilen bereits entschiedene Zugriffsanfragen über BroadcastChannel.
133
+
134
+ Schon das Laden der Datei startet die Erfassung von Console, nicht abgefangenen Fehlern und Netzwerk (XHR, fetch, WebSocket, sendBeacon, EventSource), jeweils höchstens 500 Einträge; ist der Puffer voll, fliegen zuerst einfache Logs und erfolgreiche Anfragen raus. Response-Bodys werden bis insgesamt 5 MB zwischengespeichert, 64 KB pro Body. Laden Sie die Datei deshalb synchron und früh im `<head>`.
135
+
136
+ ## Sitzungsprotokoll (Protokoll §5.4)
137
+
138
+ Diese Puffer sind das Gedächtnis einer einzelnen Seite. Parallel dazu schreibt das SDK ein **Sitzungsprotokoll** in IndexedDB (`rwd-log`) auf dem Gerät, sodass ein Agent, der sich erst nach einem Bug verbindet, trotzdem den ganzen Weg dorthin nachlesen kann:
139
+
140
+ - Eine Sitzung ist ein Start der App, gemeinsam für alle Seiten des Origins: `run({ launchId })`, sonst `window.RWDLaunchId`, sonst abgeleitet aus dem Sitzungscookie `rwd_launch` plus Heartbeat (eine Cookie-Sitzung, die über eine Stunde still war, zählt als neuer Start). `status().logSession` ist die verwendete ID.
141
+ - Aufgezeichnet werden: Öffnen der Seite / Navigation innerhalb der Seite / Vorder- und Hintergrund / Verlassen, die Taps, Eingaben, Absendungen und Scroll-Ruhepositionen des Nutzers, die interaktiven Aufrufe des Agents und `rwd.evaluate`, Wechsel der Steuerung, Console auf allen Stufen und jede abgeschlossene Anfrage – fehlgeschlagene auch mit geschwärzten Headern und Bodys (je 64 KB). Das läuft unabhängig davon, ob das Gateway erreichbar ist. Maskierte Felder werden als `••••` gespeichert, `maskPatterns` werden schon beim Schreiben der Einträge angewendet.
142
+ - Aufbewahrt werden: die letzten 3 Starts, je 10 MB; darüber hinaus werden zuerst einfache Logs und erfolgreiche Anfragen verworfen. Nur der aktuelle Start, wenn das Speicherkontingent unter 64 MB liegt; ohne IndexedDB gar nichts.
143
+ - Der Agent liest es mit `rwd.log` (`observe`) und `rwd.logDetail` (`advanced`, für Header und Bodys). Ansonsten verlässt nichts das Gerät.
144
+ - Abschalten mit `run({ record: false })` für eine Seite oder `policy.sessionLog: false` für das Projekt – was zusätzlich löscht, was dieser Origin bereits gespeichert hat.
145
+
146
+ ## Aufbau
147
+
148
+ - `src/index.ts`: öffentliche API, Sitzung, RPC-Dispatch, Zustand der Steuerung.
149
+ - `src/transport.ts`: der WebSocket der Seite (der native Konstruktor), Heartbeat-Timeout, exponentielles Backoff und nach 3 fehlgeschlagenen Versuchen alle 60 s `POST /v1/presence`.
150
+ - `src/ids.ts`: deviceId / pageId / openerId.
151
+ - `src/launch.ts`: zu welchem App-Start diese Seite gehört (`launchId`, `window.RWDLaunchId`, das Cookie `rwd_launch`).
152
+ - `src/pageWatch.ts`: `page`-Nachrichten (url, title, visibility) und Ereignisse der Zeitleiste (Navigation innerhalb der Seite, Taps des Nutzers).
153
+ - `src/ui.ts`, `src/lock.ts`: Badge, Button „Unterstützung anfordern“, Sperr-Overlay, Leuchten, Aktionshervorhebung und Dialoge in einem Shadow DOM; blockiert die vertrauenswürdigen Eingaben des Nutzers, solange ein Agent verbunden ist, und zeigt, wie lange die Verbindung schon besteht.
154
+ - `src/approval.ts`: Verbindungsfreigabe und Bestätigung sensibler Aktionen (Dialog auf der Seite oder der native Host über `nativeDecide`).
155
+ - `src/i18n.ts`, `src/locales/`, `src/localeLoader*.ts`: Sprachpakete (UI-, Aktions- und Agent-Texte pro Sprache), Auswahl und Rückfall, Nachladen bei Bedarf; `scripts/locales.mjs` baut `dist/locales/<id>.js`.
156
+ - Die Agent-Engine liegt neben chobitsu in `packages/chobitsu/src/engine/rwd/`: Snapshot, `rwd.query`, Prüfungen der Bedienbarkeit, synthetische Eingaben, Tastatur, Console- / Netzwerkpuffer, Screenshots, `rwd.storage`, das Sitzungsprotokoll in IndexedDB (`coldlog.ts`), Overlay-Erkennung (`overlays.ts`), Stufen und Bestätigungsregeln (`policy.ts`), Texte für den Agent (`i18n.ts`). Die für Snapshots verwendeten Playwright-Quellen liegen in `packages/chobitsu/src/engine/vendor/playwright/`. Der Build bündelt sie aus dem Quellcode in `dist/sdk.js`.
157
+
158
+ ## Build und Tests
159
+
160
+ ```sh
161
+ cd sdk
162
+ npm ci
163
+ npm run build # dist/sdk.js (IIFE, globales RemoteWebviewDebugger, ES2017), dist/index.mjs + index.d.ts (ES-Modul)
164
+ npm run typecheck
165
+ npm test # Playwright: WebKit (iPhone 15) + Chromium (Pixel 7)
166
+ npm run gateway # lokales Mock-Gateway: http://localhost:8787/demo/platform/?key=rwd_pk_demo
167
+ ```
168
+
169
+ Die Tests verwenden `test/mock-gateway.mjs`, das den seitenseitigen Teil des Protokolls implementiert (welcome, Zustand der Steuerung, RPCs, Presence; Tokens, Close-Codes, Stufen, Remote-Konfiguration, `agentLang`, Verbindungsfreigabe) und `/v1/sdk.js`, die Sprachpakete unter `/v1/locales/` sowie den Demo-Shop ausliefert. Es prüft selbst keine Stufen, sodass die Tests die Durchsetzung durch die Seite selbst prüfen. Die Specs in `test/e2e/` laufen mit einem `zh-CN`-Browser und `agentLang: 'zh'`, sofern ein Test nichts anderes vorgibt; `i18n.spec.ts` deckt Englisch ab, `locales.spec.ts` die übrigen Sprachpakete, Rückfall, eigene Pakete, Styling und das Layout von rechts nach links. Der Koexistenztest lädt eruda 3.4.3 und PageSpy 2.4.0 von jsdelivr und braucht daher Internetzugang.