@qzsy/dsh-bridge 3.5.3 → 3.5.4
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/CHANGELOG.md +14 -0
- package/client/client.js +26 -19
- package/client/mobile.js +29 -20
- package/package.json +2 -2
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,19 @@
|
|
|
1
1
|
# 更新日志
|
|
2
2
|
|
|
3
|
+
## [v3.5.4] - 2026-11-02
|
|
4
|
+
|
|
5
|
+
### 🐛 修复
|
|
6
|
+
|
|
7
|
+
- **接住宿主自己弹出的推理菜单**:选完模型后宿主的推理菜单可能已经挂出(层级不一定是 `body` 直接子节点);现在不再依赖我们点「推理等级」,过渡期间直接查找并 sheet 化。
|
|
8
|
+
- **推理菜单向上找定位层**:从每个 `[role="menu"]` 向上找最近的 `fixed/absolute` 承载层,兼容嵌套 portal。
|
|
9
|
+
- **给宿主 300ms 自动衔接窗口**:先等宿主自己切到推理菜单;没出现才回退到「重开父菜单 → 点推理等级」。
|
|
10
|
+
- 这样选完模型会稳定进入推理 sheet;当前模型/不同模型两条路径都覆盖。
|
|
11
|
+
|
|
12
|
+
### 🧪 验证
|
|
13
|
+
|
|
14
|
+
- 独立宿主模拟 4/4;待安装后验证真实 DSH。
|
|
15
|
+
|
|
16
|
+
|
|
3
17
|
## [v3.5.3] - 2026-11-02
|
|
4
18
|
|
|
5
19
|
### 🐛 修复
|
package/client/client.js
CHANGED
|
@@ -677,23 +677,25 @@ function setupMobileDrawer() {
|
|
|
677
677
|
};
|
|
678
678
|
const findReasoningPortal = () => {
|
|
679
679
|
if (!isMobileViewport()) return null;
|
|
680
|
-
const
|
|
681
|
-
for (const
|
|
682
|
-
if (!(el instanceof HTMLElement)) continue;
|
|
683
|
-
if (el === modelBackdrop || el === modelClone || el.classList.contains(HEADER_CLASS) || el.classList.contains(BACKDROP_CLASS)) continue;
|
|
684
|
-
if (el.hasAttribute("data-qzsy-model-sheet") || el.hasAttribute("data-qzsy-model-sheet-clone")) continue;
|
|
685
|
-
const s = getComputedStyle(el);
|
|
686
|
-
if (s.display === "none") continue;
|
|
687
|
-
if (s.position !== "fixed" && s.position !== "absolute") continue;
|
|
688
|
-
const menu = el.querySelector('[role="menu"]');
|
|
689
|
-
if (!menu) continue;
|
|
680
|
+
const roots = /* @__PURE__ */ new Set();
|
|
681
|
+
for (const menu of document.querySelectorAll('[role="menu"]')) {
|
|
690
682
|
const radios = menu.querySelectorAll('button[role="menuitemradio"], [role="menuitemradio"], input[type="radio"]').length;
|
|
691
683
|
if (radios < 1) continue;
|
|
692
684
|
const text = menu.innerText || "";
|
|
693
685
|
if (/搜索模型|Search model|DeepSeek|claude|模型与推理等级/i.test(text)) continue;
|
|
694
|
-
|
|
686
|
+
let el = menu;
|
|
687
|
+
while (el && el !== document.body) {
|
|
688
|
+
if (el.hasAttribute("data-qzsy-model-sheet") || el.hasAttribute("data-qzsy-model-sheet-clone")) break;
|
|
689
|
+
const s = getComputedStyle(el);
|
|
690
|
+
if (s.display === "none") break;
|
|
691
|
+
if (s.position === "fixed" || s.position === "absolute") {
|
|
692
|
+
roots.add(el);
|
|
693
|
+
break;
|
|
694
|
+
}
|
|
695
|
+
el = el.parentElement;
|
|
696
|
+
}
|
|
695
697
|
}
|
|
696
|
-
return
|
|
698
|
+
return [...roots].pop() || null;
|
|
697
699
|
};
|
|
698
700
|
const hostBackdropPresent = () => {
|
|
699
701
|
for (const el of document.body.children) {
|
|
@@ -930,6 +932,12 @@ function setupMobileDrawer() {
|
|
|
930
932
|
document.body.appendChild(modelClone);
|
|
931
933
|
window.setTimeout(() => {
|
|
932
934
|
if (disposed || token !== modelAdvanceToken || !modelAdvancing) return;
|
|
935
|
+
const hostReason = findReasoningPortal();
|
|
936
|
+
if (hostReason) {
|
|
937
|
+
reasoningStep = true;
|
|
938
|
+
applyModelSheet(hostReason);
|
|
939
|
+
return;
|
|
940
|
+
}
|
|
933
941
|
const findReasonCell = () => [...document.querySelectorAll('button[role="menuitem"]')].find((b) => /推理等级|Reasoning effort|Reasoning level|推理强度/i.test(b.innerText || ""));
|
|
934
942
|
const clickReasonCell = (cell) => {
|
|
935
943
|
if (!cell) return;
|
|
@@ -998,7 +1006,7 @@ function setupMobileDrawer() {
|
|
|
998
1006
|
return;
|
|
999
1007
|
}
|
|
1000
1008
|
reopenParent();
|
|
1001
|
-
},
|
|
1009
|
+
}, 300);
|
|
1002
1010
|
};
|
|
1003
1011
|
const syncModelSheet = () => {
|
|
1004
1012
|
if (disposed) return;
|
|
@@ -1007,12 +1015,11 @@ function setupMobileDrawer() {
|
|
|
1007
1015
|
return;
|
|
1008
1016
|
}
|
|
1009
1017
|
if (modelAdvancing) {
|
|
1010
|
-
|
|
1011
|
-
|
|
1012
|
-
|
|
1013
|
-
|
|
1014
|
-
|
|
1015
|
-
}
|
|
1018
|
+
const next = findReasoningPortal();
|
|
1019
|
+
if (next) {
|
|
1020
|
+
reasoningStep = true;
|
|
1021
|
+
applyModelSheet(next);
|
|
1022
|
+
return;
|
|
1016
1023
|
}
|
|
1017
1024
|
if (modelPortal && !visiblePortal(modelPortal)) modelPortal = null;
|
|
1018
1025
|
return;
|
package/client/mobile.js
CHANGED
|
@@ -501,24 +501,26 @@ export function setupMobileDrawer() {
|
|
|
501
501
|
|
|
502
502
|
const findReasoningPortal = () => {
|
|
503
503
|
if (!isMobileViewport()) return null;
|
|
504
|
-
const
|
|
505
|
-
for (const
|
|
506
|
-
if (!(el instanceof HTMLElement)) continue;
|
|
507
|
-
if (el === modelBackdrop || el === modelClone || el.classList.contains(HEADER_CLASS) || el.classList.contains(BACKDROP_CLASS)) continue;
|
|
508
|
-
if (el.hasAttribute('data-qzsy-model-sheet') || el.hasAttribute('data-qzsy-model-sheet-clone')) continue;
|
|
509
|
-
const s = getComputedStyle(el);
|
|
510
|
-
if (s.display === 'none') continue;
|
|
511
|
-
if (s.position !== 'fixed' && s.position !== 'absolute') continue;
|
|
512
|
-
const menu = el.querySelector('[role="menu"]');
|
|
513
|
-
if (!menu) continue;
|
|
504
|
+
const roots = new Set();
|
|
505
|
+
for (const menu of document.querySelectorAll('[role="menu"]')) {
|
|
514
506
|
const radios = menu.querySelectorAll('button[role="menuitemradio"], [role="menuitemradio"], input[type="radio"]').length;
|
|
515
507
|
if (radios < 1) continue;
|
|
516
508
|
const text = menu.innerText || '';
|
|
517
|
-
// 推理等级菜单只含 Off / Low / High / Max 等档位,不含模型搜索与模型分组
|
|
518
509
|
if (/搜索模型|Search model|DeepSeek|claude|模型与推理等级/i.test(text)) continue;
|
|
519
|
-
|
|
510
|
+
// 推理菜单可能不是 body 直接子节点,向上找最近的 fixed/absolute 承载层
|
|
511
|
+
let el = menu;
|
|
512
|
+
while (el && el !== document.body) {
|
|
513
|
+
if (el.hasAttribute('data-qzsy-model-sheet') || el.hasAttribute('data-qzsy-model-sheet-clone')) break;
|
|
514
|
+
const s = getComputedStyle(el);
|
|
515
|
+
if (s.display === 'none') break;
|
|
516
|
+
if (s.position === 'fixed' || s.position === 'absolute') {
|
|
517
|
+
roots.add(el);
|
|
518
|
+
break;
|
|
519
|
+
}
|
|
520
|
+
el = el.parentElement;
|
|
521
|
+
}
|
|
520
522
|
}
|
|
521
|
-
return
|
|
523
|
+
return [...roots].pop() || null;
|
|
522
524
|
};
|
|
523
525
|
|
|
524
526
|
const hostBackdropPresent = () => {
|
|
@@ -756,6 +758,13 @@ export function setupMobileDrawer() {
|
|
|
756
758
|
|
|
757
759
|
window.setTimeout(() => {
|
|
758
760
|
if (disposed || token !== modelAdvanceToken || !modelAdvancing) return;
|
|
761
|
+
// 先给宿主一点时间自己切到推理菜单;出现了就直接 sheet 化
|
|
762
|
+
const hostReason = findReasoningPortal();
|
|
763
|
+
if (hostReason) {
|
|
764
|
+
reasoningStep = true;
|
|
765
|
+
applyModelSheet(hostReason);
|
|
766
|
+
return;
|
|
767
|
+
}
|
|
759
768
|
const findReasonCell = () => [...document.querySelectorAll('button[role="menuitem"]')].find((b) => /推理等级|Reasoning effort|Reasoning level|推理强度/i.test(b.innerText || ''));
|
|
760
769
|
const clickReasonCell = (cell) => {
|
|
761
770
|
if (!cell) return;
|
|
@@ -820,7 +829,7 @@ export function setupMobileDrawer() {
|
|
|
820
829
|
return;
|
|
821
830
|
}
|
|
822
831
|
reopenParent();
|
|
823
|
-
},
|
|
832
|
+
}, 300);
|
|
824
833
|
};
|
|
825
834
|
|
|
826
835
|
const syncModelSheet = () => {
|
|
@@ -830,12 +839,12 @@ export function setupMobileDrawer() {
|
|
|
830
839
|
return;
|
|
831
840
|
}
|
|
832
841
|
if (modelAdvancing) {
|
|
833
|
-
|
|
834
|
-
|
|
835
|
-
|
|
836
|
-
|
|
837
|
-
|
|
838
|
-
|
|
842
|
+
// 宿主可能在选中模型后自己就把推理菜单挂出来了;先直接接住
|
|
843
|
+
const next = findReasoningPortal();
|
|
844
|
+
if (next) {
|
|
845
|
+
reasoningStep = true;
|
|
846
|
+
applyModelSheet(next);
|
|
847
|
+
return;
|
|
839
848
|
}
|
|
840
849
|
if (modelPortal && !visiblePortal(modelPortal)) modelPortal = null;
|
|
841
850
|
return;
|
package/package.json
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@qzsy/dsh-bridge",
|
|
3
|
-
"version": "3.5.
|
|
3
|
+
"version": "3.5.4",
|
|
4
4
|
"description": "DSH 远程隧道云官方客户端插件:一条命令把本机 DeepSeek Harness 接入云端隧道(设备码绑定、短期令牌、本地门禁代理、HTTP/SSE/WebSocket 反向隧道)。",
|
|
5
|
-
"releaseNotes": "【v3.5.
|
|
5
|
+
"releaseNotes": "【v3.5.4】模型 → 思考级别连招\\n• 接住宿主自己弹出的推理菜单,嵌套 portal 也能 sheet 化\\n• 给宿主 300ms 自动衔接窗口,没出现才回退点「推理等级」\\n• 当前模型 / 不同模型两条路径统一,推理选完才关闭",
|
|
6
6
|
"type": "module",
|
|
7
7
|
"main": "lib/index.js",
|
|
8
8
|
"exports": {
|