@mrrisega/dsh-remote 0.7.0-beta.8 → 0.7.1-beta.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (71) hide show
  1. package/clients/dsh-remote/dsh-bridge.mjs +17 -17
  2. package/clients/dsh-remote/dsh-events.mjs +6 -6
  3. package/clients/dsh-remote/e2ee-client.mjs +7 -7
  4. package/clients/dsh-remote/e2ee-shim-script.js +9 -9
  5. package/clients/dsh-remote/mobile-adapter.mjs +294 -43
  6. package/clients/dsh-remote/test/bridge-gzip.test.mjs +1 -1
  7. package/clients/dsh-remote/test/device-registration-report.test.mjs +1 -1
  8. package/clients/dsh-remote/test/dsh-events.test.mjs +10 -10
  9. package/clients/dsh-remote/test/e2ee-bridge.test.mjs +4 -4
  10. package/clients/dsh-remote/test/e2ee-client.test.mjs +7 -7
  11. package/clients/dsh-remote/test/e2ee-shim.test.mjs +1 -1
  12. package/clients/dsh-remote/test/e2ee-wecrypto-parity.test.mjs +1 -1
  13. package/clients/dsh-remote/test/harness-cookie-authority.test.mjs +4 -4
  14. package/clients/dsh-remote/test/machine-fingerprint.test.mjs +2 -2
  15. package/clients/dsh-remote/test/mobile-adapter-guards.test.mjs +6 -6
  16. package/clients/dsh-remote/test/mobile-adapter-image.test.mjs +1 -1
  17. package/clients/dsh-remote/test/mobile-adapter-runtime.test.mjs +5 -5
  18. package/clients/dsh-remote/test/mobile-adapter-settings.test.mjs +352 -0
  19. package/clients/dsh-remote/test/mobile-adapter.test.mjs +35 -0
  20. package/clients/dsh-remote/test/upstream-discovery.test.mjs +1 -1
  21. package/clients/dsh-remote/test/wechat-channel.test.mjs +5 -5
  22. package/clients/dsh-remote/test/wechat-runtime.test.mjs +26 -26
  23. package/clients/dsh-remote/test/wechat-tier-source.test.mjs +2 -2
  24. package/clients/dsh-remote/wechat-channel.mjs +9 -9
  25. package/clients/dsh-remote/wechat-runtime.mjs +38 -38
  26. package/docs/telemetry.md +3 -3
  27. package/dsh-setup.mjs +27 -27
  28. package/package.json +3 -3
  29. package/packages/dsh-remote-web/lib/client.js +56 -56
  30. package/packages/dsh-remote-web/lib/fix-prompt.js +1 -1
  31. package/packages/dsh-remote-web/lib/index.js +380 -59
  32. package/packages/dsh-remote-web/lib/tarball-update.js +1 -1
  33. package/packages/dsh-remote-web/package.json +1 -1
  34. package/packages/dsh-remote-web/runtime/clients/dsh-remote/dsh-bridge.mjs +17 -17
  35. package/packages/dsh-remote-web/runtime/clients/dsh-remote/dsh-events.mjs +6 -6
  36. package/packages/dsh-remote-web/runtime/clients/dsh-remote/e2ee-client.mjs +7 -7
  37. package/packages/dsh-remote-web/runtime/clients/dsh-remote/e2ee-shim-script.js +9 -9
  38. package/packages/dsh-remote-web/runtime/clients/dsh-remote/mobile-adapter.mjs +294 -43
  39. package/packages/dsh-remote-web/runtime/clients/dsh-remote/wechat-channel.mjs +9 -9
  40. package/packages/dsh-remote-web/runtime/clients/dsh-remote/wechat-runtime.mjs +38 -38
  41. package/packages/dsh-remote-web/runtime/clients/dsh-web/native.html +5 -5
  42. package/packages/dsh-remote-web/runtime/dsh-setup.mjs +27 -27
  43. package/packages/dsh-remote-web/test/account-switch-device.test.mjs +2 -2
  44. package/packages/dsh-remote-web/test/activation-single-point.test.mjs +1 -1
  45. package/packages/dsh-remote-web/test/announcements-ui.test.mjs +1 -1
  46. package/packages/dsh-remote-web/test/connect-loop.test.mjs +1 -1
  47. package/packages/dsh-remote-web/test/connect-ui.test.mjs +2 -2
  48. package/packages/dsh-remote-web/test/desktop-compat.test.mjs +4 -4
  49. package/packages/dsh-remote-web/test/diag-report.test.mjs +1 -1
  50. package/packages/dsh-remote-web/test/fix-prompt.test.mjs +2 -2
  51. package/packages/dsh-remote-web/test/harness-restart.test.mjs +1 -1
  52. package/packages/dsh-remote-web/test/install-profile-targets.test.mjs +3 -3
  53. package/packages/dsh-remote-web/test/installer-cli.test.mjs +1 -1
  54. package/packages/dsh-remote-web/test/launchd-domain.test.mjs +2 -2
  55. package/packages/dsh-remote-web/test/patch-activation.test.mjs +2 -2
  56. package/packages/dsh-remote-web/test/picker-pin.test.mjs +1 -1
  57. package/packages/dsh-remote-web/test/plugin-manifest.test.mjs +2 -2
  58. package/packages/dsh-remote-web/test/quota-absent.test.mjs +4 -4
  59. package/packages/dsh-remote-web/test/remote-access-ui.test.mjs +2 -2
  60. package/packages/dsh-remote-web/test/selfheal-restart-guard.test.mjs +420 -0
  61. package/packages/dsh-remote-web/test/settings-entry-placement.test.mjs +6 -6
  62. package/packages/dsh-remote-web/test/settings-entry.test.mjs +2 -2
  63. package/packages/dsh-remote-web/test/settings-open-path.test.mjs +4 -4
  64. package/packages/dsh-remote-web/test/setup-output.test.mjs +11 -11
  65. package/packages/dsh-remote-web/test/tarball-update.test.mjs +1 -1
  66. package/packages/dsh-remote-web/test/telemetry.test.mjs +4 -4
  67. package/packages/dsh-remote-web/test/uninstall-safety.test.mjs +2 -2
  68. package/packages/dsh-remote-web/test/watcher-upstream-port.test.mjs +1 -1
  69. package/packages/dsh-remote-web/test/wechat-bot-ui.test.mjs +7 -7
  70. package/packages/dsh-remote-web/test/windows-compat.test.mjs +5 -5
  71. package/scripts/test-net-guard.cjs +1 -1
@@ -16,7 +16,7 @@
16
16
  // ⑦ 控制面缺失(bridge 没跑/版本旧)要说清楚怎么办,**绝不**留一个永久 spinner;
17
17
  // ⑧ 无障碍:真 <button>、aria-live 播报、不靠颜色单独表意。
18
18
  //
19
- // 【0.6.12 新增】产品引导(业主口径:「动效引导」+ 微信通道要求已注册并登录):
19
+ // 【0.6.12 新增】产品引导(用户约定:「动效引导」+ 微信通道要求已注册并登录):
20
20
  // ⑨ 首屏导览:未绑定时内容体最上面三行讲清用途(推送 / 回数字拍板 / 微信里交代任务),
21
21
  // DOM 顺序在「连接微信机器人」之前,且是小字紧凑排版(不把按钮挤出首屏);
22
22
  // ⑩ 登录门:未登录**不渲染**微信 tab,登录后当场出现(不刷新页面);会话在 tab 开着时失效
@@ -355,7 +355,7 @@ test("入口:settings.section 里**只有**「📱 远程访问」一个栏目
355
355
  const list = plugin.sectionList();
356
356
  const ids = list.map((m) => m.id);
357
357
  // 【0.6.11 改断言】旧断言 deepEqual(ids, ["dsh-remote", "dsh-remote-wechat"]) + order 31 + label 含
358
- // 「🤖 微信机器人」编码的是**旧行为**(微信面板作为第二个设置栏目)。业主口径:「不要给它单独弄
358
+ // 「🤖 微信机器人」编码的是**旧行为**(微信面板作为第二个设置栏目)。用户约定:「不要给它单独弄
359
359
  // 一个菜单,直接放到『远程控制』面板里面」→ 第二个栏目已删,这里改为断言「只有一个栏目」。
360
360
  assert.deepEqual(ids, [ROOT_SECTION_ID], `设置页只应有一个栏目,实际:${ids.join(",")}`);
361
361
  assert.equal(list.length, 1, "settings.section 注册次数必须恰好是 1(不多不少)");
@@ -426,7 +426,7 @@ test("tab 条(home 与 wechat 共用):第三个 tab 是「微信机器人
426
426
  });
427
427
 
428
428
  test("绿泡泡与零外部资源(源码级):.dru-wx-ico 是微信品牌绿、不新增任何外部资源/依赖", () => {
429
- // 图标颜色:微信品牌绿 #07c160(业主口径:「增加上微信的绿泡泡小图标」)
429
+ // 图标颜色:微信品牌绿 #07c160(用户约定:「增加上微信的绿泡泡小图标」)
430
430
  assert.match(SOURCE, /\.dru-wx-ico\{[^}]*color:#07c160/, "绿泡泡必须是微信品牌绿 #07c160");
431
431
  // 装饰性:节点上 aria-hidden(可读名字来自同 tab 的文字标签,见上一条用例)
432
432
  assert.match(SOURCE, /className: "dru-wx-ico", "aria-hidden": "true"/, "图标节点必须 aria-hidden");
@@ -499,10 +499,10 @@ test("首屏导览:未绑定时就在最上面(DOM 顺序在「连接微信
499
499
  assert.ok(textHas(intro, "继续已有任务"), "③ 要明说免费也能继续已有任务(回复即续接)");
500
500
  assert.ok(textHas(intro, "开新任务"), "③ 要明说「在微信里开新任务」是会员能力");
501
501
  assert.ok(textHas(intro, "切换会话"), "③ 要明说「切换会话」是会员能力");
502
- // ★ 分层必须如实写在面板上:免费用户要能看出**付费多什么**(业主:"增加一个对比展示")。
502
+ // ★ 分层必须如实写在面板上:免费用户要能看出**付费多什么**(用户:"增加一个对比展示")。
503
503
  // 面板里含糊其辞 → 用户绑完去微信发句话拿到付费提示 → 只会觉得产品骗人。
504
504
  assert.ok(textHas(intro, "会员"), "必须标出哪些是会员能力(不能含糊)");
505
- assert.ok(textHas(intro, "额度"), "免费档要写明每月消息额度(业主:免费给每月 N 条)");
505
+ assert.ok(textHas(intro, "额度"), "免费档要写明每月消息额度(用户:免费给每月 N 条)");
506
506
  // 未绑定/未读到状态时不显示锁,免得闪一下
507
507
  assert.ok(!textHas(intro, "🔒") || textHas(intro, "会员"), "锁必须配「会员」字样,不能只给一个符号");
508
508
 
@@ -513,7 +513,7 @@ test("首屏导览:未绑定时就在最上面(DOM 顺序在「连接微信
513
513
  assert.ok(introAt < btnAt, `导览必须排在连接按钮之前(导览 #${introAt},按钮 #${btnAt})`);
514
514
  // 而且紧凑块排在内容体最前面:不会把连接按钮推到需要滚动才看得见的地方
515
515
  // (harness 渲染时会对普通节点做浅拷贝,所以拿树里的同一个节点比,不比组件里的原对象)
516
- // 【0.6.18】内容体第一个孩子变成了「两步走」操作引导块(.dru-wx-guide):用户口径是
516
+ // 【0.6.18】内容体第一个孩子变成了「两步走」操作引导块(.dru-wx-guide):用户约定是
517
517
  // 先在微信通道首屏讲清"这是干啥用的 + 两步怎么接",再给"你现在能用哪些能力"的清单 ——
518
518
  // 所以导览降为**第二个**孩子,连接按钮仍在首屏(两块都是紧凑小字卡片)。
519
519
  assert.equal(embed.children[0], find(embed, (n) => n.props?.className === "dru-wx-guide"),
@@ -923,7 +923,7 @@ test("★★ 面板能力镜像必须与运行时判定表一致(否则面板
923
923
  //
924
924
  // 上面那条镜像一致性用例保证的是「冷启动兜底等于运行时内置表」;
925
925
  // 下面这三条保证的是**服务端一旦下发了权益包,面板就以它为准** ——
926
- // 这是业主「后台改权限无需发版」与「话术与权限必须一致、不多承诺」的交汇点:
926
+ // 这是用户「后台改权限无需发版」与「话术与权限必须一致、不多承诺」的交汇点:
927
927
  // 后台把免费额度从 20 改成 5,面板必须当场说 5;说 20 就是让用户按 20 去发、
928
928
  // 第 6 条被拦,然后认为产品坏了。
929
929
  // ---------------------------------------------------------------------------
@@ -1,7 +1,7 @@
1
1
  /**
2
2
  * Windows 兼容回归(0.6.7 新增)。
3
3
  *
4
- * 背景(真实事故,用户诊断报告 + 本地逐条复现):
4
+ * 背景(真实故障,用户诊断报告 + 本地逐条复现):
5
5
  * dsh-remote-web 0.6.6 及更早的整套「服务状态 / 启停 / 重启」按 macOS/Linux 写死,
6
6
  * 在 Windows 上**运行期必死**——安装与网络都正常,坏的全是运行期:
7
7
  * ① launchTarget() 无条件调 process.getuid():Windows 没有这个 API(typeof !== "function")
@@ -267,7 +267,7 @@ test("win32:重启 harness 生成 node 助手(不再 /bin/sh),且生成
267
267
  });
268
268
 
269
269
  test("契约:插件里不存在「裸 spawn」——每个子进程都必须有 'error' 监听(否则打挂宿主)", () => {
270
- // 事故原文:spawn("/bin/sh") 在 Windows ENOENT,而 ChildProcess 没有 'error' 监听
270
+ // 故障原文:spawn("/bin/sh") 在 Windows ENOENT,而 ChildProcess 没有 'error' 监听
271
271
  // → 未捕获异常把 dsh web 打挂,且代码已经先把「已调度重启」写进日志、返回成功。
272
272
  // 生成的 Windows 助手源码是模板字符串(它自己挂了 error 监听),先从「真实代码」里剔除
273
273
  const helperStart = INDEX_SRC.indexOf("function buildRestartHelperSource(");
@@ -425,7 +425,7 @@ test("win32:dsh-setup 注册任务计划程序登录任务(不再只说「
425
425
  test("win32:彻底卸载会删掉任务计划条目(否则下次登录又被拉起来)", () => {
426
426
  const uninstall = INDEX_SRC.slice(INDEX_SRC.indexOf("function uninstallRuntime("), INDEX_SRC.indexOf("// ---------- DeepSeek harness 重启"));
427
427
  assert.ok(/schtasks", \["\/Delete", "\/TN", WIN_TASK_NAME, "\/F"\]/.test(uninstall), "卸载应删除 Windows 登录任务");
428
- assert.ok(/servicePlatform: isDarwin\(\) \? "launchd"/.test(uninstall), "servicePlatform 应包含 Windows 口径");
428
+ assert.ok(/servicePlatform: isDarwin\(\) \? "launchd"/.test(uninstall), "servicePlatform 应包含 Windows 约定");
429
429
  });
430
430
 
431
431
  test("win32:dsh-setup 生成的「重启 dsh web」助手也是合法可执行的 JS", async () => {
@@ -465,7 +465,7 @@ test("前端:bridge-status 轮询失败不再静默(旧版让面板永久停
465
465
  });
466
466
 
467
467
  test("测试隔离:套件不得访问任何外部地址(生产限流会被测试污染)", () => {
468
- // 事故(2026-09-19):有用例在配置里写了假账号却没覆盖 api_url → 按默认地址请求**生产中继**,
468
+ // 故障(2026-09-19):有用例在配置里写了假账号却没覆盖 api_url → 按默认地址请求**生产中继**,
469
469
  // 其中 /api/device-login 带假密码必然失败,而服务端登录限流按**出口 IP** 计(5 次/15 分钟)——
470
470
  // 结果不仅污染生产审计,还让**本机自己的 bridge 被连坐**(拿不到 JWT),
471
471
  // 真机表现成"切换账号后设备一直登记不上去",排查方向被彻底带偏。
@@ -564,7 +564,7 @@ test("win32:登录任务经 wscript+VBS 隐藏启动(旧版会弹黑色空
564
564
  test("win32:桌面端(Electron 解释器)自启动必须先设 ELECTRON_RUN_AS_NODE=1", async () => {
565
565
  // 现场价值:DeepSeek Harness 桌面端宿主里 process.execPath 是 Electron 应用二进制。
566
566
  // 不设这个变量,自启动拉起的不是 bridge 守护,而是**又开一个桌面端应用** ——
567
- // 表现为「服务登记成功、进程秒退、bridge 永远起不来」,与 0.6.15 端口事故一样难排查。
567
+ // 表现为「服务登记成功、进程秒退、bridge 永远起不来」,与 0.6.15 端口故障一样难排查。
568
568
  const dir = await mkdtemp(path.join(os.tmpdir(), "dsh-win-electron-"));
569
569
  try {
570
570
  const src = SETUP_SRC.slice(
@@ -1,7 +1,7 @@
1
1
  /**
2
2
  * 测试期网络护栏(NODE_OPTIONS=--require 注入,见 package.json 的 test 脚本)。
3
3
  *
4
- * 为什么必须有(2026-09-19 实测事故):
4
+ * 为什么必须有(2026-09-19 实测故障):
5
5
  * 有测试用例在 profile 配置里写了**假账号**(phone/password)却没覆盖 `api_url`,
6
6
  * 于是插件按默认地址去请求**生产中继** `https://n.risegao.cn:…`。其中
7
7
  * `/api/device-login` 带着假密码必然失败,而服务端的登录限流是**按出口 IP**