dsh-remote-web 0.6.15 → 0.6.16

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.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "dsh-remote-web",
3
- "version": "0.6.15",
3
+ "version": "0.6.16",
4
4
  "description": "公网远程控制 DeepSeek Harness(dsh web):安装即得专属加密地址,人在外面也能用手机访问电脑上的 dsh——无需同一局域网/WiFi、无需公网 IP 与内网穿透,全程加密;手机端 100% 还原电脑体验(对话/工具/审批/设置)。技术用户可选自建服务,流量走自己的服务器。Remote control DeepSeek Harness (dsh web) from anywhere over the public internet — install, get an encrypted URL, use it from your phone on any network (dual-half cordis plugin: Settings panel + same-origin /dsh-remote routes). (2026-09 由 dsh-remote-ui 更名 / renamed from dsh-remote-ui; dsh-remote 的 dsh web 插件半,不是纯 UI/皮肤插件)",
5
5
  "type": "module",
6
6
  "main": "lib/index.js",
@@ -100,33 +100,6 @@ const RUNTIME_HOST_RE =
100
100
  /(data-sidebar-collapsed|data-details-collapsed|data-rightbar-collapsed|data-shell-overlay)|(pI_x6G_frame|hHd-Xa_root|hHd-Xa_toggle)/;
101
101
 
102
102
  const STYLE = `
103
- /* ===== 首屏加载提示(0.6.14)=====
104
- 为什么要有它:镜像页首屏要拉 dsh web 的全部客户端插件(实测 ~14 MB,一个不可拆分的
105
- /plugins/?? 聚合请求),免费档限速下几十秒起步。此前页面上**只有官方那个转圈**,
106
- 用户无法区分"在加载"和"卡死了",只能反复刷新 —— 反而更慢。
107
- 这里给一句人话提示 + 分阶段的补充说明,加载完成(或超时兜底)即自动移除。
108
- ⚠️ 刻意**不**放进 @media (max-width:820px):Windows/桌面浏览器打开镜像页同样要等。
109
- ⚠️ pointer-events:none + 半透明:万一移除逻辑失效,也绝不挡住任何点击。 */
110
- .dsh-ma-boot {
111
- position: fixed; inset: 0; z-index: 2147483000;
112
- display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 14px;
113
- background: color-mix(in srgb, var(--dsw-alias-bg-base, #0f1115) 88%, transparent);
114
- backdrop-filter: blur(2px);
115
- pointer-events: none;
116
- font-family: inherit; text-align: center; padding: 24px;
117
- transition: opacity .3s ease;
118
- }
119
- .dsh-ma-boot[data-fading="1"] { opacity: 0; }
120
- .dsh-ma-boot-spin {
121
- width: 34px; height: 34px; border-radius: 50%;
122
- border: 3px solid color-mix(in srgb, currentColor 22%, transparent);
123
- border-top-color: currentColor;
124
- animation: dsh-ma-boot-spin 1s linear infinite;
125
- }
126
- @keyframes dsh-ma-boot-spin { to { transform: rotate(360deg); } }
127
- .dsh-ma-boot-title { font-size: 15px; font-weight: 600; }
128
- .dsh-ma-boot-sub { font-size: 13px; line-height: 1.6; opacity: .75; max-width: 22em; }
129
- .dsh-ma-boot-elapsed { font-size: 12px; opacity: .55; font-variant-numeric: tabular-nums; }
130
103
 
131
104
  @media (max-width: 820px) {
132
105
  html, body { max-width: 100%; overflow-x: hidden; }
@@ -458,88 +431,25 @@ html[data-dsh-ma-merged-e2ee] #dsh-e2ee-badge { display: none !important; }
458
431
  const SCRIPT = `(() => {
459
432
  "use strict";
460
433
 
461
- /* ===== 首屏加载提示(0.6.14)=====
462
- 用户反馈:「普通用户加载进入镜像页面时等待时间较长,目前等待过程中一直在转圈」
463
- —— 官方那个转圈不告诉用户任何事。这里在**页面解析的第一时间**就挂上一条人话提示,
464
- 并在官方 UI 就绪(或兜底超时)后自动移除。
434
+ /* ===== 【0.6.16 已删除】首屏加载提示层(0.6.14 引入,0.6.15 仍在)=====
435
+ 为什么删掉(业主实测,2026-09-25):「界面都已经加载完了,十几秒就把插件的接口加载好了,
436
+ 但这个遮罩一直不消失」—— 截图里官方 UI 就在下面透出来,秒表走到 187 秒。
437
+
438
+ 根因是**设计错误**,不是某个选择器写错:
439
+ · 那是个 position:fixed / inset:0 / z-index:2147483000 的**全屏层**(88% 不透明背景 +
440
+ backdrop-blur),视觉上盖住整个应用;
441
+ · 它唯一的退出条件是 maBootLooksReady() 这组**DOM 启发式**(官方 frame 的
442
+ data-*-collapsed / 类名前缀,或 textarea/[contenteditable]/[role=textbox])。
443
+ 官方改版、会话尚未挂载输入框、或前缀变化时两组信号全不命中 → 层就永远留着。
444
+ · 当时我给自己写的安慰是「pointer-events:none,万一移除失效也绝不挡住点击」——
445
+ 可对用户来说,**盖住视线和进不去没有区别**:刷新也一样,每次都要等 4 分钟兜底。
446
+ 结论(业主要求):**直接删掉这个功能**。首屏反馈交给官方自己的转圈;
447
+ 我们不再在用户页面上放任何会覆盖整屏的东西 —— 这类层一旦判断失误就是"永远进不去",
448
+ 代价远大于它带来的提示价值(何况限速放开后首屏本来就快了)。
449
+
450
+ 护栏见 test/mobile-adapter-guards.test.mjs:适配层不得再引入全屏覆盖层。 */
451
+ void 0;
465
452
 
466
- ⚠️ 必须放在所有主机判定(HOSTISH / NARROW)之前:首屏慢的正是这些判定等不到的时候。
467
- ⚠️ 只做提示,不做任何拦截:pointer-events:none,也没有遮罩语义。 */
468
- var maBootTip = null, maBootTimers = [], maBootStart = Date.now(), maBootElapsedTimer = 0, maBootWatchTimer = 0;
469
- function maBootSet(cls, text) {
470
- try { var n = maBootTip && maBootTip.querySelector(cls); if (n) n.textContent = text; } catch (e) { /* 忽略 */ }
471
- }
472
- function maBootShow() {
473
- try {
474
- if (maBootTip) return;
475
- if (!document.body) return; // 解析太早(body 还没出来)→ 交给 DOMContentLoaded 再挂
476
- maBootTip = document.createElement("div");
477
- maBootTip.className = "dsh-ma-boot";
478
- maBootTip.setAttribute("role", "status");
479
- maBootTip.setAttribute("aria-live", "polite");
480
- maBootTip.innerHTML =
481
- '<div class="dsh-ma-boot-spin" aria-hidden="true"></div>' +
482
- '<div class="dsh-ma-boot-title">正在加载远程桌面…</div>' +
483
- '<div class="dsh-ma-boot-sub">首次打开需要下载较完整的前端资源,请稍候</div>' +
484
- '<div class="dsh-ma-boot-elapsed">已等待 0 秒</div>';
485
- document.body.appendChild(maBootTip);
486
- // 秒表:让"到底等了多久"可见(用户据此判断是慢还是死了)
487
- maBootElapsedTimer = setInterval(function () {
488
- try {
489
- var s = Math.floor((Date.now() - maBootStart) / 1000);
490
- var n = maBootTip && maBootTip.querySelector(".dsh-ma-boot-elapsed");
491
- if (n) n.textContent = "已等待 " + s + " 秒";
492
- } catch (e) { /* 忽略 */ }
493
- }, 1000);
494
- maBootTimers.push(setTimeout(function () {
495
- maBootSet(".dsh-ma-boot-sub", "网络较慢时可能需要一两分钟;加载完成后会自动进入,不用重复刷新");
496
- }, 8000));
497
- maBootTimers.push(setTimeout(function () {
498
- maBootSet(".dsh-ma-boot-sub", "还在加载…如果长时间停在这里,可以下拉刷新重试(重复刷新不会更快)");
499
- }, 30 * 1000));
500
- } catch (e) { /* 提示失败绝不影响主功能 */ }
501
- }
502
- function maBootHide() {
503
- try {
504
- for (var i = 0; i < maBootTimers.length; i++) clearTimeout(maBootTimers[i]);
505
- maBootTimers = [];
506
- if (maBootElapsedTimer) { clearInterval(maBootElapsedTimer); maBootElapsedTimer = 0; }
507
- if (maBootWatchTimer) { try { clearInterval(maBootWatchTimer); } catch (e) { /* 忽略 */ } maBootWatchTimer = 0; }
508
- var tip = maBootTip;
509
- maBootTip = null;
510
- if (tip && tip.parentNode) {
511
- try { tip.setAttribute("data-fading", "1"); } catch (e) { /* 忽略 */ }
512
- setTimeout(function () { try { if (tip.parentNode) tip.parentNode.removeChild(tip); } catch (e) { /* 忽略 */ } }, 300);
513
- }
514
- } catch (e) { /* 忽略 */ }
515
- }
516
- /** 官方 UI 是否已经可用了(= 提示可以撤了)。 */
517
- function maBootLooksReady() {
518
- try {
519
- // ① 适配层认出来的官方 frame(与下方 boot() 同一组选择器)
520
- if (document.querySelector(".pI_x6G_frame, [data-sidebar-collapsed], [data-details-collapsed], [data-rightbar-collapsed]")) return true;
521
- // ② 出现输入框/会话区也算"进来了"(官方改版首选信号失灵时的兜底)
522
- return Boolean(document.querySelector('textarea, [contenteditable="true"], [role="textbox"]'));
523
- } catch (e) { return false; }
524
- }
525
- if (document.readyState === "loading") {
526
- document.addEventListener("DOMContentLoaded", maBootShow);
527
- } else {
528
- maBootShow();
529
- }
530
- // 轮询撤下:1s 一次,成本可忽略(只是两次 querySelector);一旦撤下就自我停止。
531
- // 上限与"4 分钟兜底"对齐,避免页面异常时留下常驻定时器。
532
- maBootWatchTimer = setInterval(function () {
533
- if (maBootLooksReady()) { maBootHide(); return; }
534
- if (!maBootTip) { try { clearInterval(maBootWatchTimer); } catch (e) { /* 忽略 */ } maBootWatchTimer = 0; }
535
- }, 1000);
536
- maBootTimers.push(setTimeout(function () { maBootHide(); }, 240 * 1000));
537
- // 页面卸载/进 bfcache 时收干净(测试与真机都靠这条不留悬挂定时器)
538
- try {
539
- var maBootBye = function () { maBootHide(); };
540
- window.addEventListener("pagehide", maBootBye);
541
- window.addEventListener("unload", maBootBye);
542
- } catch (e) { /* 忽略 */ }
543
453
 
544
454
  /* —— 主机门解除(2026-09):镜像页(如 n.risegao.cn)经设备流认证回连同一台 127.0.0.1:3080,
545
455
  桥已把 Host 回环化并剥 Origin(不扩大信任面)。官方客户端以 transport.ownsHost 判定