@wenbin_wb/dsh-bridge 2.11.0 → 2.11.2
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 +36 -0
- package/client/client.js +57 -19
- package/client/index.js +21 -9
- package/client/mobile-styles.js +45 -11
- package/docs/release-process.md +6 -1
- package/docs/telegram-usage.md +1 -1
- package/lib/feishu/node.js +439 -439
- package/lib/index.js +37 -12
- package/lib/platform/base.js +147 -147
- package/lib/platform/dsh-storage.js +117 -117
- package/lib/platform/index.js +10 -10
- package/lib/platform/message-split.js +229 -229
- package/lib/platform/stream-slices.js +21 -21
- package/lib/restart-helper.mjs +17 -3
- package/lib/telegram/node.js +322 -322
- package/lib/wechat/gateway.js +986 -986
- package/lib/wechat/media.js +285 -285
- package/lib/wechat/node.js +352 -352
- package/package.json +3 -3
package/CHANGELOG.md
CHANGED
|
@@ -4,6 +4,42 @@
|
|
|
4
4
|
|
|
5
5
|
---
|
|
6
6
|
|
|
7
|
+
## [v2.11.2] - 2026-10-02
|
|
8
|
+
|
|
9
|
+
> 本版为移动端修复版:解决英文界面下侧边栏(抽屉)点击后空白,以及 DSH 0.1.7 升级后右侧栏点击后不显示的问题。
|
|
10
|
+
|
|
11
|
+
### 🐞 修复
|
|
12
|
+
|
|
13
|
+
- **移动端侧边栏(抽屉)点击后空白**:宿主按钮 aria-label 随界面语言切换(中文「打开侧边栏」/ 英文 "Open sidebar"),插件此前只按中文匹配宿主按钮,英文界面下漏取 → 抽屉滑出但会话列表不挂载。现将抽屉展开/收起/会话操作/新建会话等工作区按钮一律中英双语匹配(英文界面与中文界面行为一致)。
|
|
14
|
+
- **移动端右侧栏点击后不显示**:DSH 0.1.7 把宿主布局外壳改为 grid 三列布局(sidebar | center | rightbar),并把右侧栏全屏面板从 `fixed` 改为 `absolute` 相对右侧栏列定位;插件旧规则把框架强制成 flex 单列、且面板 top 让位二次叠加,导致面板被定位到视口外(点开按钮后按钮消失、右侧栏不出来)。现恢复宿主 grid 布局并显式归位三列,面板统一强制 fixed + 顶栏下方让位(兼容 0.1.5 与 0.1.7 宿主)。
|
|
15
|
+
|
|
16
|
+
### 🧪 测试
|
|
17
|
+
|
|
18
|
+
- 新增 `test/browser/mobile-sidebar-drawer.mjs`(抽屉展开/收起,中英文按钮匹配)与 `test/browser/mobile-sidebar-right.mjs`(右侧栏 grid 布局)两个真实浏览器验收套件(共 8 套件);`test/mobile-fixed-panel-offset.test.mjs` 新增面板 fixed 与 frame grid 归位结构断言;`test/client-provide.test.mjs` 新增宿主按钮中英双语匹配断言。全量 340 项测试 100% 通过。
|
|
19
|
+
- 清理 CodeQL note 级告警 `js/unused-local-variable`(测试文件未使用导入)。
|
|
20
|
+
|
|
21
|
+
> ⚠️ 生效说明:纯前端改动,刷新页面即生效(无需重启 dsh)。
|
|
22
|
+
|
|
23
|
+
---
|
|
24
|
+
|
|
25
|
+
## [v2.11.1] - 2026-10-02
|
|
26
|
+
|
|
27
|
+
> 本版为修复版:解决 DSH 0.1.7 升级后暴露的移动端「看不到最新消息」、设置弹窗层级误抬,以及 linux 下托管误判导致的 systemd 掉线问题。
|
|
28
|
+
|
|
29
|
+
### 🐞 修复
|
|
30
|
+
|
|
31
|
+
- **手机上聊天区「看不到最新消息」(PR #48,感谢 imroc)**:移动端主框架规则原用 `div[class*="_frame"]` 跨包通配选择器,除了命中有意的布局外壳(`[data-slot="root"]` 直接子元素),还会误伤 DSH 0.1.7 新增的聊天记录容器(`dsh-client-ui-chat` 的 `.EvIC1a_frame`)——给它强加 `height:100dvh + overflow:hidden` 后被钳到视口高度、溢出内容被裁掉,而外层滚动区已到底,表现为「看到旧消息、看不到最新消息」。现选择器收窄为 `[data-slot="root"] > div[class*="_frame"]`,仅命中布局外壳;对 0.1.5 / 0.1.6 宿主无行为差异。
|
|
32
|
+
- **linux 下托管误判与 systemd 掉线**:真实 `/proc/self/cgroup` 带末尾换行且 cgroup v1 为多行,原解析按单行整体切分,导致 `endsWith('.service')` 判定失败、托管器被误判为 `self`,`Restart=on-failure` 下 dsh 掉线不自动拉起。现逐行解析并 trim;同时重启前为 `systemctl` 补齐默认 PATH 与 `XDG_RUNTIME_DIR`(`--user` 场景)、加 5s 执行超时兜底、自动创建日志目录。
|
|
33
|
+
- **设置弹窗自身被层级规则误抬(适配 DSH 0.1.7)**:0.1.7 把设置弹窗(`VOzbGW_overlay`)从 `#root` 内部移为 `<body>` 直接子级,满足「body 子级 + 含 `role=dialog` 子元素」的抬升特征,被一并抬到第三方模态同层,退化成按 DOM 顺序决胜,「安装确认框被盖住」可能复发。现抬升规则排除设置弹窗自身,仍只抬其它顶层模态。
|
|
34
|
+
|
|
35
|
+
### 🧪 测试
|
|
36
|
+
|
|
37
|
+
- 新增 `test/restart-dsh.test.mjs` cgroup 多行/换行回归断言;`test/mobile-fixed-panel-offset.test.mjs` 新增 frame 规则限定回归守卫;`test/mobile-settings-narrow-layout.test.mjs` 新增抬升规则排除断言。全量 338 项测试 100% 通过。
|
|
38
|
+
|
|
39
|
+
> ⚠️ 生效说明:客户端样式刷新页面即生效;重启守护逻辑改动需重启 dsh 后生效。
|
|
40
|
+
|
|
41
|
+
---
|
|
42
|
+
|
|
7
43
|
## [v2.11.0] - 2026-09-28
|
|
8
44
|
|
|
9
45
|
> 本版为客户端架构升级与环境解耦:支持桌面端宿主(如 Tauri)将设置面板作为独立组件嵌入并动态管理设置页入口;同时为 Android 移动壳及第三方自适应插件引入环境自适应让位与多级特性开关,消除界面冲突与遮挡。
|
package/client/client.js
CHANGED
|
@@ -78,7 +78,12 @@ var MOBILE_STYLES_CSS = `
|
|
|
78
78
|
\u5F39\u7A97\u4E4B\u4E0A\u5E76\u76D6\u4F4F\u8BBE\u7F6E\u9875\u3002\u8FD9\u662F\u300C\u6A21\u6001\u5C31\u8BE5\u76D6\u5728\u8BBE\u7F6E\u5F39\u7A97\u4E4B\u4E0A\u300D\u7684\u65E2\u5B9A\u53D6\u820D\uFF1A\u5B81\u53EF\u8BA9\u771F\u6A21\u6001
|
|
79
79
|
\u53EF\u89C1\uFF0C\u4E5F\u4E0D\u63A5\u53D7"\u5F39\u4E86\u5374\u70B9\u4E0D\u5230"\u3002\u72EC\u7ACB\u9A8C\u6536\u5DF2\u5B9E\u6D4B\u8BE5\u6784\u9020\u4F1A\u547D\u4E2D\uFF1B\u82E5\u5C06\u6765\u771F\u8E29\u5230\uFF0C
|
|
80
80
|
\u5E94\u6539\u4E3A\u6309\u300C\u8BE5\u6D6E\u5C42\u662F\u5426\u53EF\u5173\u95ED\u300D\u8FDB\u4E00\u6B65\u6536\u7A84\uFF0C\u800C\u4E0D\u662F\u56DE\u9000\u8FD9\u6761\u89C4\u5219\u3002 */
|
|
81
|
-
|
|
81
|
+
/* \u26A0\uFE0F \u5FC5\u987B\u6392\u9664\u8BBE\u7F6E\u5F39\u7A97\u81EA\u8EAB\uFF1ADSH 0.1.7 \u628A VOzbGW_overlay \u53D8\u6210\u4E86 <body> \u7684\u76F4\u63A5\u5B50\u7EA7
|
|
82
|
+
\uFF080.1.5 \u91CC\u5B83\u5D4C\u5728 #root \u5185\u90E8\uFF09\uFF0C\u5B83\u540C\u6837\u6EE1\u8DB3\u300Cbody \u5B50\u7EA7 + \u542B role=dialog \u5B50\u5143\u7D20\u300D\uFF0C
|
|
83
|
+
\u4F1A\u88AB\u672C\u6761\u4E00\u5E76\u62AC\u5230 10050 \u2014\u2014 \u4E8E\u662F\u4E0E\u7B2C\u4E09\u65B9\u6A21\u6001\u6839\u540C\u5C42\u3001\u9000\u5316\u6210\u6309 DOM \u987A\u5E8F\u51B3\u80DC\uFF0C
|
|
84
|
+
\u521A\u4FEE\u597D\u7684\u300C\u5B89\u88C5\u786E\u8BA4\u6846\u88AB\u76D6\u4F4F\u300D\u5C31\u53EF\u80FD\u590D\u53D1\u3002:not(...) \u628A\u5B83\u6392\u9664\uFF0C\u8BA9\u8BBE\u7F6E\u5F39\u7A97\u7EE7\u7EED\u7531
|
|
85
|
+
\u5B83\u81EA\u5DF1\u7684 10002 \u89C4\u5219\u5B9A\u4F4D\uFF0C\u672C\u6761\u53EA\u62AC**\u5176\u5B83**\u9876\u5C42\u6A21\u6001\u3002 */
|
|
86
|
+
body:has(div[class*="VOzbGW_overlay"]) > div:has(> div[class*="mask"], > div[role="dialog"]):not([class*="VOzbGW_overlay"]) {
|
|
82
87
|
z-index: 10050 !important;
|
|
83
88
|
}
|
|
84
89
|
|
|
@@ -104,31 +109,60 @@ var MOBILE_STYLES_CSS = `
|
|
|
104
109
|
\uFF08dsh-client-ui-sidebar-right/lib/client.js\uFF09\uFF0C\u6545\u79FB\u52A8\u7AEF\u6837\u5F0F\u53D6 <=767px\uFF0C
|
|
105
110
|
768px \u8D77\u5F7B\u5E95\u4EA4\u8FD8\u684C\u9762\u5E03\u5C40\uFF0C\u907F\u514D"\u6865\u6E32\u67D3\u9876\u680F\u3001\u5BBF\u4E3B\u5374\u672A\u5168\u5C4F"\u7684\u9519\u4F4D\u3002 */
|
|
106
111
|
@media (max-width: 767px) {
|
|
107
|
-
/* 1. \u4E3B\u6846\u67B6\u4E3A Header \u817E\u51FA\u9876\u90E8\u7A7A\u95F4
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
112
|
+
/* 1. \u4E3B\u6846\u67B6\u4E3A Header \u817E\u51FA\u9876\u90E8\u7A7A\u95F4\u3002
|
|
113
|
+
|
|
114
|
+
\u9009\u62E9\u5668\u5FC5\u987B\u9650\u5B9A\u5728\u5E03\u5C40\u5916\u58F3\uFF08dsh-client-ui-layout \u7684 AppFrame\uFF0C\u5373
|
|
115
|
+
[data-slot="root"] \u7684\u76F4\u63A5\u5B50\u5143\u7D20\uFF09\u3002\u5BBF\u4E3B\u7684 CSS-module \u54C8\u5E0C\u53EA\u4FDD\u8BC1\u540C\u6587\u4EF6
|
|
116
|
+
\u5185\u552F\u4E00\uFF0C*="_frame" \u662F\u8DE8\u5305\u901A\u914D\uFF1A\u804A\u5929\u8BB0\u5F55\u5BB9\u5668\uFF08dsh-client-ui-chat \u7684
|
|
117
|
+
.EvIC1a_frame\uFF0C\u540C\u6837\u4EE5 _frame \u7ED3\u5C3E\uFF09\u4E5F\u4F1A\u88AB\u547D\u4E2D\u3002\u4E00\u65E6\u547D\u4E2D\uFF0C\u5B83\u88AB\u5F3A\u52A0
|
|
118
|
+
height:100dvh + overflow:hidden\uFF0C\u5728\u624B\u673A\u4E0A\u88AB\u94B3\u5230\u89C6\u53E3\u9AD8\u5EA6\u5E76\u88C1\u6389\u6EA2\u51FA\u5185\u5BB9\uFF1A
|
|
119
|
+
\u5916\u5C42 [data-conversation-scroll] \u5DF2\u6EDA\u5230\u5E95\u3001\u5185\u90E8\u5374\u8FD8\u6709\u6570\u5343 px \u8BFB\u4E0D\u5230\uFF0C
|
|
120
|
+
\u8868\u73B0\u4E3A\u300C\u770B\u4E0D\u5230\u6700\u65B0\u6D88\u606F\u300D\u3002\u5B98\u65B9\u7ED9\u8BE5\u5BB9\u5668\u7684\u89C4\u5219\u662F flex:none;height:auto
|
|
121
|
+
\uFF08\u8BA9\u8BB0\u5F55\u968F\u5185\u5BB9\u81EA\u7136\u589E\u9AD8\u3001\u7531\u5916\u5C42\u7EDF\u4E00\u6EDA\u52A8\uFF09\uFF0C\u4E0E\u8FD9\u91CC\u51B2\u7A81\uFF0C\u6545\u5FC5\u987B\u6392\u9664\u3002 */
|
|
122
|
+
[data-slot="root"] > div[class*="_frame"] {
|
|
123
|
+
display: grid !important;
|
|
124
|
+
grid-template-columns: 0px minmax(0px, 1fr) minmax(0px, 0px) !important;
|
|
125
|
+
grid-template-rows: minmax(0, 100%) !important;
|
|
111
126
|
width: 100vw !important;
|
|
112
127
|
height: 100dvh !important;
|
|
113
128
|
margin: 0 !important;
|
|
114
129
|
padding-top: var(--dsh-mobile-header-h) !important;
|
|
115
130
|
position: relative !important;
|
|
116
|
-
grid-template-columns: 1fr !important;
|
|
117
131
|
overflow: hidden !important;
|
|
118
132
|
box-sizing: border-box !important;
|
|
119
133
|
}
|
|
120
134
|
|
|
135
|
+
/* \u5BBF\u4E3B 0.1.7 \u7684 frame \u662F grid \u4E09\u5217\u5E03\u5C40\uFF08sidebar | center | rightbar\uFF09\uFF0CJS \u6309\u72B6\u6001\u6CE8\u5165
|
|
136
|
+
grid-template-columns\uFF1B\u63D2\u4EF6\u628A\u5DE6\u4FA7\u680F\u62BD\u5C49\u5316\u540E sidebarCol \u53D8\u6210 fixed\uFF08\u8131\u79BB grid \u6D41\uFF09\uFF0C
|
|
137
|
+
\u82E5\u4E0D\u663E\u5F0F\u6307\u5B9A\u5217\u4F4D\uFF0CcenterCol \u4F1A\u88AB\u81EA\u52A8\u6392\u8FDB\u7B2C 1 \u5217\uFF0856px \u8F68\u9053\uFF09\u3001rightbarCol \u584C\u9677\u5230
|
|
138
|
+
\u89C6\u53E3\u5E95\u90E8 \u2192 \u53F3\u4FA7\u680F\u70B9\u5F00\u540E\u9762\u677F\u88AB\u5B9A\u4F4D\u5230\u89C6\u53E3\u5916\uFF08\u7528\u6237\u770B\u5230\u7684\u300C\u6309\u94AE\u6D88\u5931\u3001\u53F3\u4FA7\u680F\u6CA1\u51FA\u6765\u300D\uFF09\u3002
|
|
139
|
+
\u8FD9\u91CC\u663E\u5F0F\u5F52\u4F4D\uFF1Asidebar \u62BD\u5C49\u4E0D\u5360\u5217\uFF08\u7B2C 1 \u5217 0px\uFF09\u3001center \u5360\u6EE1\uFF08\u7B2C 2 \u5217 1fr\uFF09\u3001
|
|
140
|
+
rightbar \u4FDD\u7559\u5BBF\u4E3B\u53F3\u4FA7\u680F\u5217\uFF08\u7B2C 3 \u5217 0px \u6298\u53E0\uFF0C\u5168\u5C4F\u9762\u677F fixed \u76F8\u5BF9\u89C6\u53E3\u3001\u4E0D\u4F9D\u8D56\u6B64\u5217\uFF09\u3002 */
|
|
141
|
+
div[class*="_centerCol"] { grid-column: 2 !important; }
|
|
142
|
+
div[class*="_rightbarCol"] { grid-column: 3 !important; }
|
|
143
|
+
div[class*="_overlayLayer"] { grid-column: 1 / -1 !important; }
|
|
144
|
+
|
|
121
145
|
/* 1.1 fixed \u5168\u5C4F\u9762\u677F\u5355\u72EC\u8BA9\u4F4D\uFF1Aposition:fixed \u7684\u5305\u542B\u5757\u662F viewport\uFF08CSS 2.1 \xA710.1\uFF09\uFF0C
|
|
122
146
|
\u4E0D\u8DDF\u968F\u4E0A\u9762 frame \u7684 padding-top\uFF0C\u56E0\u6B64\u9876\u90E8 52px \u4F1A\u843D\u8FDB\u9876\u680F\u8986\u76D6\u533A\uFF08#41\uFF09\u3002
|
|
123
|
-
\u5B98\u65B9\u53F3\u4FA7\u680F\u5728 <768px \u81EA\u52A8\u5168\u5C4F\
|
|
124
|
-
|
|
125
|
-
\
|
|
126
|
-
\
|
|
127
|
-
\
|
|
147
|
+
\u5B98\u65B9\u53F3\u4FA7\u680F\u5728 <768px \u81EA\u52A8\u5168\u5C4F\uFF0C\u8FD9\u91CC\u6309 data \u5C5E\u6027\u76F4\u63A5\u4F4D\u79FB\u5BB9\u5668\u672C\u8EAB\uFF0C\u4E0D\u4F9D\u8D56\u5BBF\u4E3B
|
|
148
|
+
CSS-module \u54C8\u5E0C\u7C7B\u540D\u3002
|
|
149
|
+
\u5BBF\u4E3B\u7248\u672C\u5DEE\u5F02\uFF080.1.5 vs 0.1.7\uFF09\uFF1A0.1.5 \u7684\u9762\u677F\u81EA\u8EAB\u5C31\u662F position:fixed; inset:0
|
|
150
|
+
\uFF08\u76F8\u5BF9\u89C6\u53E3\uFF09\uFF0Ctop \u8BA9\u4F4D\u76F4\u63A5\u751F\u6548\uFF1B0.1.7 \u628A\u9762\u677F\u6539\u6210 position:absolute \u76F8\u5BF9
|
|
151
|
+
rightbarCol \u5217\u5B9A\u4F4D\uFF0C\u4E14\u5BBF\u4E3B\u5DF2\u628A\u5B83\u653E\u5728\u5185\u5BB9\u533A\u8D77\u70B9\u2014\u2014\u82E5\u63D2\u4EF6\u4ECD\u53EA\u6539 top\uFF0C\u4F1A\u5728\u5BBF\u4E3B
|
|
152
|
+
\u5B9A\u4F4D\u4E4B\u4E0A\u518D\u53E0\u52A0 52px\uFF08\u9762\u677F\u88AB\u63A8\u5230\u89C6\u53E3\u5916\uFF0C\u8868\u73B0\u4E3A\u300C\u70B9\u5F00\u53F3\u4FA7\u680F\u6309\u94AE\u6D88\u5931\u3001\u9762\u677F\u4E0D
|
|
153
|
+
\u51FA\u6765\u300D\uFF09\u3002\u4FEE\u6CD5\uFF1A\u628A\u9762\u677F\u7EDF\u4E00\u5F3A\u5236\u4E3A fixed \u76F8\u5BF9\u89C6\u53E3 + top:52px \u8BA9\u4F4D\uFF0C\u4E24\u7248\u5BBF\u4E3B
|
|
154
|
+
\u884C\u4E3A\u4E00\u81F4\u3002 */
|
|
128
155
|
[data-sidebar-right-panel="fullscreen"] {
|
|
156
|
+
position: fixed !important;
|
|
129
157
|
top: var(--dsh-mobile-header-h, 52px) !important;
|
|
158
|
+
left: 0 !important;
|
|
159
|
+
right: 0 !important;
|
|
160
|
+
bottom: 0 !important;
|
|
161
|
+
width: 100vw !important;
|
|
130
162
|
height: calc(100dvh - var(--dsh-mobile-header-h, 52px)) !important;
|
|
131
163
|
max-height: calc(100dvh - var(--dsh-mobile-header-h, 52px)) !important;
|
|
164
|
+
z-index: 40 !important;
|
|
165
|
+
box-sizing: border-box !important;
|
|
132
166
|
}
|
|
133
167
|
|
|
134
168
|
/* 2. \u9876\u90E8\u539F\u751F\u5BFC\u822A\u6761\uFF1A100% \u8FD8\u539F DeepSeek App (\u5DE6\u4FA7\u53CC\u6A2A\u7EBF\uFF0C\u53F3\u4FA7(+)\uFF0C\u4E2D\u95F4\u7559\u767D\uFF0C\u65E0\u591A\u4F59\u8BBE\u7F6E\u6309\u94AE) */
|
|
@@ -5886,7 +5920,9 @@ function setupMobileExperience(rpcCall, ctx) {
|
|
|
5886
5920
|
e.stopPropagation();
|
|
5887
5921
|
const isOpen = document.body.classList.toggle("dsh-drawer-open");
|
|
5888
5922
|
if (isOpen) {
|
|
5889
|
-
const expand = document.querySelector(
|
|
5923
|
+
const expand = document.querySelector(
|
|
5924
|
+
'button[aria-label*="\u6253\u5F00\u4FA7\u8FB9\u680F"], button[title*="\u6253\u5F00\u4FA7\u8FB9\u680F"], button[aria-label*="Open sidebar"], button[title*="Open sidebar"]'
|
|
5925
|
+
);
|
|
5890
5926
|
if (expand) expand.click();
|
|
5891
5927
|
}
|
|
5892
5928
|
};
|
|
@@ -5910,7 +5946,7 @@ function setupMobileExperience(rpcCall, ctx) {
|
|
|
5910
5946
|
rightBtn.onclick = () => {
|
|
5911
5947
|
const openPanels = document.querySelectorAll('div[class*="nArs4W_panel"]:not([class*="panelHidden"]), div[class*="workbench_panel"]:not([class*="panelHidden"])');
|
|
5912
5948
|
openPanels.forEach((p) => p.classList.add("nArs4W_panelHidden"));
|
|
5913
|
-
const dshNewBtn = document.querySelector('button[aria-label="\u65B0\u5EFA\u4F1A\u8BDD"]');
|
|
5949
|
+
const dshNewBtn = document.querySelector('button[aria-label="\u65B0\u5EFA\u4F1A\u8BDD"], button[aria-label="New session"]');
|
|
5914
5950
|
if (dshNewBtn) dshNewBtn.click();
|
|
5915
5951
|
};
|
|
5916
5952
|
header.appendChild(leftBtn);
|
|
@@ -5963,7 +5999,7 @@ function setupMobileExperience(rpcCall, ctx) {
|
|
|
5963
5999
|
e.stopPropagation();
|
|
5964
6000
|
document.body.classList.remove("dsh-workbench-open");
|
|
5965
6001
|
p.classList.add("nArs4W_panelHidden");
|
|
5966
|
-
const collapseBtn = document.querySelector('button[class*="toggleButton"][aria-label*="\u6536\u8D77"]');
|
|
6002
|
+
const collapseBtn = document.querySelector('button[class*="toggleButton"][aria-label*="\u6536\u8D77"], button[class*="toggleButton"][aria-label*="Collapse"]');
|
|
5967
6003
|
if (collapseBtn) collapseBtn.click();
|
|
5968
6004
|
};
|
|
5969
6005
|
bar.appendChild(btn);
|
|
@@ -5975,14 +6011,14 @@ function setupMobileExperience(rpcCall, ctx) {
|
|
|
5975
6011
|
window.addEventListener("resize", ensurePanelCloseButton);
|
|
5976
6012
|
document.addEventListener("click", (e) => {
|
|
5977
6013
|
if (typeof window === "undefined" || window.innerWidth > MOBILE_MAX_WIDTH) return;
|
|
5978
|
-
const trigger = e.target.closest('button[aria-label*="\u9762\u677F"], button[aria-label*="\u5DE5\u4F5C\u533A"], div[class*="toggleCluster"] button, button[class*="subagent"], div[class*="headerActions"] button, div[class*="titleRow"] button');
|
|
6014
|
+
const trigger = e.target.closest('button[aria-label*="\u9762\u677F"], button[aria-label*="\u5DE5\u4F5C\u533A"], button[aria-label*="workspace"], button[aria-label*="Workspace"], div[class*="toggleCluster"] button, button[class*="subagent"], div[class*="headerActions"] button, div[class*="titleRow"] button');
|
|
5979
6015
|
if (trigger && !trigger.classList.contains("dsh-mobile-panel-close-btn") && !trigger.classList.contains("dsh-header-menu-btn") && !trigger.classList.contains("dsh-header-new-btn")) {
|
|
5980
6016
|
document.body.classList.add("dsh-workbench-open");
|
|
5981
6017
|
}
|
|
5982
6018
|
}, true);
|
|
5983
6019
|
document.addEventListener("click", (e) => {
|
|
5984
6020
|
if (typeof window === "undefined" || window.innerWidth > MOBILE_MAX_WIDTH) return;
|
|
5985
|
-
const toggle = e.target.closest('button[aria-label*="\u6536\u8D77\u4FA7\u8FB9\u680F"], button[title*="\u6536\u8D77\u4FA7\u8FB9\u680F"]');
|
|
6021
|
+
const toggle = e.target.closest('button[aria-label*="\u6536\u8D77\u4FA7\u8FB9\u680F"], button[title*="\u6536\u8D77\u4FA7\u8FB9\u680F"], button[aria-label*="Collapse sidebar"], button[title*="Collapse sidebar"]');
|
|
5986
6022
|
if (toggle) {
|
|
5987
6023
|
document.body.classList.remove("dsh-drawer-open");
|
|
5988
6024
|
}
|
|
@@ -6054,7 +6090,7 @@ function setupMobileExperience(rpcCall, ctx) {
|
|
|
6054
6090
|
if (navigator.vibrate) navigator.vibrate(40);
|
|
6055
6091
|
} catch (_) {
|
|
6056
6092
|
}
|
|
6057
|
-
const actionBtn = sessionRow.querySelector('button[aria-label*="\u64CD\u4F5C"], button[class*="iconButton"], button');
|
|
6093
|
+
const actionBtn = sessionRow.querySelector('button[aria-label*="\u64CD\u4F5C"], button[aria-label*="Session actions"], button[class*="iconButton"], button');
|
|
6058
6094
|
if (actionBtn) {
|
|
6059
6095
|
actionBtn.click();
|
|
6060
6096
|
}
|
|
@@ -6081,7 +6117,9 @@ function setupMobileExperience(rpcCall, ctx) {
|
|
|
6081
6117
|
if (Math.abs(deltaX) > 60 && Math.abs(deltaX) > Math.abs(deltaY) * 1.5) {
|
|
6082
6118
|
if (deltaX > 0 && touchStartX <= 35) {
|
|
6083
6119
|
document.body.classList.add("dsh-drawer-open");
|
|
6084
|
-
const collapsedToggle = document.querySelector(
|
|
6120
|
+
const collapsedToggle = document.querySelector(
|
|
6121
|
+
'div[class*="hHd-Xa_collapsed"] button[class*="hHd-Xa_toggle"], button[aria-label*="\u6253\u5F00\u4FA7\u8FB9\u680F"], button[title*="\u6253\u5F00\u4FA7\u8FB9\u680F"], button[aria-label*="Open sidebar"], button[title*="Open sidebar"]'
|
|
6122
|
+
);
|
|
6085
6123
|
if (collapsedToggle) collapsedToggle.click();
|
|
6086
6124
|
} else if (deltaX < 0 && document.body.classList.contains("dsh-drawer-open")) {
|
|
6087
6125
|
document.body.classList.remove("dsh-drawer-open");
|
|
@@ -6094,7 +6132,7 @@ function setupMobileExperience(rpcCall, ctx) {
|
|
|
6094
6132
|
if (!btn) return;
|
|
6095
6133
|
if (btn.closest("#dsh-remote-workspace-modal")) return;
|
|
6096
6134
|
const label = (btn.getAttribute("aria-label") || btn.innerText || btn.title || "").trim();
|
|
6097
|
-
const isAddWorkspace = label === "\u6DFB\u52A0\u5DE5\u4F5C\u533A" || label === "\u65B0\u5EFA\u5DE5\u4F5C\u533A" || label === "\u6253\u5F00\u5DE5\u4F5C\u533A" || label === "\u6253\u5F00\u6587\u4EF6\u5939" || label === "Add Workspace" || label === "Open Folder" || label.includes("\u6DFB\u52A0\u5DE5\u4F5C\u533A") || label.includes("\u6253\u5F00\u5DE5\u4F5C\u533A") || label.includes("\u6253\u5F00\u6587\u4EF6\u5939") || btn.matches('button[aria-label*="\u5DE5\u4F5C\u533A"][aria-label*="\u6DFB\u52A0"], button[aria-label*="\u5DE5\u4F5C\u533A"][aria-label*="\u6253\u5F00"]');
|
|
6135
|
+
const isAddWorkspace = label === "\u6DFB\u52A0\u5DE5\u4F5C\u533A" || label === "\u65B0\u5EFA\u5DE5\u4F5C\u533A" || label === "\u6253\u5F00\u5DE5\u4F5C\u533A" || label === "\u6253\u5F00\u6587\u4EF6\u5939" || label === "Add Workspace" || label === "Open Folder" || label.includes("\u6DFB\u52A0\u5DE5\u4F5C\u533A") || label.includes("\u6253\u5F00\u5DE5\u4F5C\u533A") || label.includes("\u6253\u5F00\u6587\u4EF6\u5939") || btn.matches('button[aria-label*="\u5DE5\u4F5C\u533A"][aria-label*="\u6DFB\u52A0"], button[aria-label*="\u5DE5\u4F5C\u533A"][aria-label*="\u6253\u5F00"], button[aria-label*="Workspace"][aria-label*="add"], button[aria-label*="Workspace"][aria-label*="open"], button[aria-label*="Add workspace"], button[aria-label*="Open workspace"]');
|
|
6098
6136
|
if (isAddWorkspace) {
|
|
6099
6137
|
e.preventDefault();
|
|
6100
6138
|
e.stopPropagation();
|
package/client/index.js
CHANGED
|
@@ -3950,7 +3950,12 @@ function setupMobileExperience(rpcCall, ctx) {
|
|
|
3950
3950
|
e.stopPropagation();
|
|
3951
3951
|
const isOpen = document.body.classList.toggle('dsh-drawer-open');
|
|
3952
3952
|
if (isOpen) {
|
|
3953
|
-
|
|
3953
|
+
// 匹配宿主「展开侧边栏」按钮。宿主文案随界面语言切换:中文「打开侧边栏」、
|
|
3954
|
+
// 英文 "Open sidebar"(0.1.7 起宿主按浏览器语言渲染 en,只匹配中文会漏取,
|
|
3955
|
+
// 导致抽屉滑出但会话列表未挂载 → 侧边栏空白)。
|
|
3956
|
+
const expand = document.querySelector(
|
|
3957
|
+
'button[aria-label*="打开侧边栏"], button[title*="打开侧边栏"], button[aria-label*="Open sidebar"], button[title*="Open sidebar"]',
|
|
3958
|
+
);
|
|
3954
3959
|
if (expand) expand.click();
|
|
3955
3960
|
}
|
|
3956
3961
|
};
|
|
@@ -3978,7 +3983,8 @@ function setupMobileExperience(rpcCall, ctx) {
|
|
|
3978
3983
|
rightBtn.onclick = () => {
|
|
3979
3984
|
const openPanels = document.querySelectorAll('div[class*="nArs4W_panel"]:not([class*="panelHidden"]), div[class*="workbench_panel"]:not([class*="panelHidden"])');
|
|
3980
3985
|
openPanels.forEach((p) => p.classList.add('nArs4W_panelHidden'));
|
|
3981
|
-
|
|
3986
|
+
// 宿主新建会话按钮文案随语言切换:中文「新建会话」/ 英文 "New session"(两者都要匹配,否则英文界面下 (+) 失效)
|
|
3987
|
+
const dshNewBtn = document.querySelector('button[aria-label="新建会话"], button[aria-label="New session"]');
|
|
3982
3988
|
if (dshNewBtn) dshNewBtn.click();
|
|
3983
3989
|
};
|
|
3984
3990
|
|
|
@@ -4038,7 +4044,7 @@ function setupMobileExperience(rpcCall, ctx) {
|
|
|
4038
4044
|
e.stopPropagation();
|
|
4039
4045
|
document.body.classList.remove('dsh-workbench-open');
|
|
4040
4046
|
p.classList.add('nArs4W_panelHidden');
|
|
4041
|
-
const collapseBtn = document.querySelector('button[class*="toggleButton"][aria-label*="收起"]');
|
|
4047
|
+
const collapseBtn = document.querySelector('button[class*="toggleButton"][aria-label*="收起"], button[class*="toggleButton"][aria-label*="Collapse"]');
|
|
4042
4048
|
if (collapseBtn) collapseBtn.click();
|
|
4043
4049
|
};
|
|
4044
4050
|
bar.appendChild(btn);
|
|
@@ -4051,18 +4057,22 @@ function setupMobileExperience(rpcCall, ctx) {
|
|
|
4051
4057
|
window.addEventListener('resize', ensurePanelCloseButton);
|
|
4052
4058
|
|
|
4053
4059
|
// 移动端点击面板/工作区触发按钮时,自动激活 dsh-workbench-open
|
|
4060
|
+
// (宿主文案随语言切换:中文「面板/工作区」/ 英文 "Panel/workspace" —— 注意英文实际是
|
|
4061
|
+
// 小写 "Add workspace"、"Choose workspace" 与大写 "Workspace actions for …",两者都要覆盖;
|
|
4062
|
+
// CSS 属性子串匹配区分大小写,不能只写一种)
|
|
4054
4063
|
document.addEventListener('click', (e) => {
|
|
4055
4064
|
if (typeof window === 'undefined' || window.innerWidth > MOBILE_MAX_WIDTH) return;
|
|
4056
|
-
const trigger = e.target.closest('button[aria-label*="面板"], button[aria-label*="工作区"], div[class*="toggleCluster"] button, button[class*="subagent"], div[class*="headerActions"] button, div[class*="titleRow"] button');
|
|
4065
|
+
const trigger = e.target.closest('button[aria-label*="面板"], button[aria-label*="工作区"], button[aria-label*="workspace"], button[aria-label*="Workspace"], div[class*="toggleCluster"] button, button[class*="subagent"], div[class*="headerActions"] button, div[class*="titleRow"] button');
|
|
4057
4066
|
if (trigger && !trigger.classList.contains('dsh-mobile-panel-close-btn') && !trigger.classList.contains('dsh-header-menu-btn') && !trigger.classList.contains('dsh-header-new-btn')) {
|
|
4058
4067
|
document.body.classList.add('dsh-workbench-open');
|
|
4059
4068
|
}
|
|
4060
4069
|
}, true);
|
|
4061
4070
|
|
|
4062
4071
|
// 移动端点击 DSH 自带的收起侧边栏图标时,自动收起抽屉
|
|
4072
|
+
// (文案随宿主界面语言切换:中文「收起侧边栏」/ 英文 "Collapse sidebar",两者都要匹配)
|
|
4063
4073
|
document.addEventListener('click', (e) => {
|
|
4064
4074
|
if (typeof window === 'undefined' || window.innerWidth > MOBILE_MAX_WIDTH) return;
|
|
4065
|
-
const toggle = e.target.closest('button[aria-label*="收起侧边栏"], button[title*="收起侧边栏"]');
|
|
4075
|
+
const toggle = e.target.closest('button[aria-label*="收起侧边栏"], button[title*="收起侧边栏"], button[aria-label*="Collapse sidebar"], button[title*="Collapse sidebar"]');
|
|
4066
4076
|
if (toggle) {
|
|
4067
4077
|
document.body.classList.remove('dsh-drawer-open');
|
|
4068
4078
|
}
|
|
@@ -4170,8 +4180,8 @@ function setupMobileExperience(rpcCall, ctx) {
|
|
|
4170
4180
|
if (navigator.vibrate) navigator.vibrate(40);
|
|
4171
4181
|
} catch (_) {}
|
|
4172
4182
|
|
|
4173
|
-
//
|
|
4174
|
-
const actionBtn = sessionRow.querySelector('button[aria-label*="操作"], button[class*="iconButton"], button');
|
|
4183
|
+
// 寻找该会话项内的三点操作按钮并触发点击(宿主文案:中文「操作」/ 英文 "Session actions")
|
|
4184
|
+
const actionBtn = sessionRow.querySelector('button[aria-label*="操作"], button[aria-label*="Session actions"], button[class*="iconButton"], button');
|
|
4175
4185
|
if (actionBtn) {
|
|
4176
4186
|
actionBtn.click();
|
|
4177
4187
|
}
|
|
@@ -4202,7 +4212,9 @@ function setupMobileExperience(rpcCall, ctx) {
|
|
|
4202
4212
|
if (Math.abs(deltaX) > 60 && Math.abs(deltaX) > Math.abs(deltaY) * 1.5) {
|
|
4203
4213
|
if (deltaX > 0 && touchStartX <= 35) {
|
|
4204
4214
|
document.body.classList.add('dsh-drawer-open');
|
|
4205
|
-
const collapsedToggle = document.querySelector(
|
|
4215
|
+
const collapsedToggle = document.querySelector(
|
|
4216
|
+
'div[class*="hHd-Xa_collapsed"] button[class*="hHd-Xa_toggle"], button[aria-label*="打开侧边栏"], button[title*="打开侧边栏"], button[aria-label*="Open sidebar"], button[title*="Open sidebar"]',
|
|
4217
|
+
);
|
|
4206
4218
|
if (collapsedToggle) collapsedToggle.click();
|
|
4207
4219
|
} else if (deltaX < 0 && document.body.classList.contains('dsh-drawer-open')) {
|
|
4208
4220
|
document.body.classList.remove('dsh-drawer-open');
|
|
@@ -4234,7 +4246,7 @@ function setupMobileExperience(rpcCall, ctx) {
|
|
|
4234
4246
|
label.includes('添加工作区') ||
|
|
4235
4247
|
label.includes('打开工作区') ||
|
|
4236
4248
|
label.includes('打开文件夹') ||
|
|
4237
|
-
btn.matches('button[aria-label*="工作区"][aria-label*="添加"], button[aria-label*="工作区"][aria-label*="打开"]')
|
|
4249
|
+
btn.matches('button[aria-label*="工作区"][aria-label*="添加"], button[aria-label*="工作区"][aria-label*="打开"], button[aria-label*="Workspace"][aria-label*="add"], button[aria-label*="Workspace"][aria-label*="open"], button[aria-label*="Add workspace"], button[aria-label*="Open workspace"]')
|
|
4238
4250
|
);
|
|
4239
4251
|
|
|
4240
4252
|
if (isAddWorkspace) {
|
package/client/mobile-styles.js
CHANGED
|
@@ -47,7 +47,12 @@ export const MOBILE_STYLES_CSS = `
|
|
|
47
47
|
弹窗之上并盖住设置页。这是「模态就该盖在设置弹窗之上」的既定取舍:宁可让真模态
|
|
48
48
|
可见,也不接受"弹了却点不到"。独立验收已实测该构造会命中;若将来真踩到,
|
|
49
49
|
应改为按「该浮层是否可关闭」进一步收窄,而不是回退这条规则。 */
|
|
50
|
-
|
|
50
|
+
/* ⚠️ 必须排除设置弹窗自身:DSH 0.1.7 把 VOzbGW_overlay 变成了 <body> 的直接子级
|
|
51
|
+
(0.1.5 里它嵌在 #root 内部),它同样满足「body 子级 + 含 role=dialog 子元素」,
|
|
52
|
+
会被本条一并抬到 10050 —— 于是与第三方模态根同层、退化成按 DOM 顺序决胜,
|
|
53
|
+
刚修好的「安装确认框被盖住」就可能复发。:not(...) 把它排除,让设置弹窗继续由
|
|
54
|
+
它自己的 10002 规则定位,本条只抬**其它**顶层模态。 */
|
|
55
|
+
body:has(div[class*="VOzbGW_overlay"]) > div:has(> div[class*="mask"], > div[role="dialog"]):not([class*="VOzbGW_overlay"]) {
|
|
51
56
|
z-index: 10050 !important;
|
|
52
57
|
}
|
|
53
58
|
|
|
@@ -73,31 +78,60 @@ export const MOBILE_STYLES_CSS = `
|
|
|
73
78
|
(dsh-client-ui-sidebar-right/lib/client.js),故移动端样式取 <=767px,
|
|
74
79
|
768px 起彻底交还桌面布局,避免"桥渲染顶栏、宿主却未全屏"的错位。 */
|
|
75
80
|
@media (max-width: 767px) {
|
|
76
|
-
/* 1. 主框架为 Header
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
81
|
+
/* 1. 主框架为 Header 腾出顶部空间。
|
|
82
|
+
|
|
83
|
+
选择器必须限定在布局外壳(dsh-client-ui-layout 的 AppFrame,即
|
|
84
|
+
[data-slot="root"] 的直接子元素)。宿主的 CSS-module 哈希只保证同文件
|
|
85
|
+
内唯一,*="_frame" 是跨包通配:聊天记录容器(dsh-client-ui-chat 的
|
|
86
|
+
.EvIC1a_frame,同样以 _frame 结尾)也会被命中。一旦命中,它被强加
|
|
87
|
+
height:100dvh + overflow:hidden,在手机上被钳到视口高度并裁掉溢出内容:
|
|
88
|
+
外层 [data-conversation-scroll] 已滚到底、内部却还有数千 px 读不到,
|
|
89
|
+
表现为「看不到最新消息」。官方给该容器的规则是 flex:none;height:auto
|
|
90
|
+
(让记录随内容自然增高、由外层统一滚动),与这里冲突,故必须排除。 */
|
|
91
|
+
[data-slot="root"] > div[class*="_frame"] {
|
|
92
|
+
display: grid !important;
|
|
93
|
+
grid-template-columns: 0px minmax(0px, 1fr) minmax(0px, 0px) !important;
|
|
94
|
+
grid-template-rows: minmax(0, 100%) !important;
|
|
80
95
|
width: 100vw !important;
|
|
81
96
|
height: 100dvh !important;
|
|
82
97
|
margin: 0 !important;
|
|
83
98
|
padding-top: var(--dsh-mobile-header-h) !important;
|
|
84
99
|
position: relative !important;
|
|
85
|
-
grid-template-columns: 1fr !important;
|
|
86
100
|
overflow: hidden !important;
|
|
87
101
|
box-sizing: border-box !important;
|
|
88
102
|
}
|
|
89
103
|
|
|
104
|
+
/* 宿主 0.1.7 的 frame 是 grid 三列布局(sidebar | center | rightbar),JS 按状态注入
|
|
105
|
+
grid-template-columns;插件把左侧栏抽屉化后 sidebarCol 变成 fixed(脱离 grid 流),
|
|
106
|
+
若不显式指定列位,centerCol 会被自动排进第 1 列(56px 轨道)、rightbarCol 塌陷到
|
|
107
|
+
视口底部 → 右侧栏点开后面板被定位到视口外(用户看到的「按钮消失、右侧栏没出来」)。
|
|
108
|
+
这里显式归位:sidebar 抽屉不占列(第 1 列 0px)、center 占满(第 2 列 1fr)、
|
|
109
|
+
rightbar 保留宿主右侧栏列(第 3 列 0px 折叠,全屏面板 fixed 相对视口、不依赖此列)。 */
|
|
110
|
+
div[class*="_centerCol"] { grid-column: 2 !important; }
|
|
111
|
+
div[class*="_rightbarCol"] { grid-column: 3 !important; }
|
|
112
|
+
div[class*="_overlayLayer"] { grid-column: 1 / -1 !important; }
|
|
113
|
+
|
|
90
114
|
/* 1.1 fixed 全屏面板单独让位:position:fixed 的包含块是 viewport(CSS 2.1 §10.1),
|
|
91
115
|
不跟随上面 frame 的 padding-top,因此顶部 52px 会落进顶栏覆盖区(#41)。
|
|
92
|
-
官方右侧栏在 <768px
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
116
|
+
官方右侧栏在 <768px 自动全屏,这里按 data 属性直接位移容器本身,不依赖宿主
|
|
117
|
+
CSS-module 哈希类名。
|
|
118
|
+
宿主版本差异(0.1.5 vs 0.1.7):0.1.5 的面板自身就是 position:fixed; inset:0
|
|
119
|
+
(相对视口),top 让位直接生效;0.1.7 把面板改成 position:absolute 相对
|
|
120
|
+
rightbarCol 列定位,且宿主已把它放在内容区起点——若插件仍只改 top,会在宿主
|
|
121
|
+
定位之上再叠加 52px(面板被推到视口外,表现为「点开右侧栏按钮消失、面板不
|
|
122
|
+
出来」)。修法:把面板统一强制为 fixed 相对视口 + top:52px 让位,两版宿主
|
|
123
|
+
行为一致。 */
|
|
97
124
|
[data-sidebar-right-panel="fullscreen"] {
|
|
125
|
+
position: fixed !important;
|
|
98
126
|
top: var(--dsh-mobile-header-h, 52px) !important;
|
|
127
|
+
left: 0 !important;
|
|
128
|
+
right: 0 !important;
|
|
129
|
+
bottom: 0 !important;
|
|
130
|
+
width: 100vw !important;
|
|
99
131
|
height: calc(100dvh - var(--dsh-mobile-header-h, 52px)) !important;
|
|
100
132
|
max-height: calc(100dvh - var(--dsh-mobile-header-h, 52px)) !important;
|
|
133
|
+
z-index: 40 !important;
|
|
134
|
+
box-sizing: border-box !important;
|
|
101
135
|
}
|
|
102
136
|
|
|
103
137
|
/* 2. 顶部原生导航条:100% 还原 DeepSeek App (左侧双横线,右侧(+),中间留白,无多余设置按钮) */
|
package/docs/release-process.md
CHANGED
|
@@ -20,7 +20,12 @@
|
|
|
20
20
|
|
|
21
21
|
1. **改版本**:`package.json` 的 `version` + `releaseNotes`
|
|
22
22
|
2. **写 CHANGELOG**:`CHANGELOG.md` 顶部新增对应版本条目
|
|
23
|
-
3.
|
|
23
|
+
3. **构建与测试**:
|
|
24
|
+
- `npm run build:client`(**必须**:客户端产物要与源码同步,`npm test` 有一项断言会校验产物内嵌的 CSS 与源码逐字一致)
|
|
25
|
+
- `npm test` + `npm run lint`
|
|
26
|
+
- `npm run verify:mobile-ui`(**发布前必做**:跑真实 GUI 的移动端行为验收,8 个套件。需要 dsh web 正在运行;Chrome 路径可用 `PUPPETEER_EXECUTABLE_PATH` 指定。它不在 CI 里跑,因为 CI 没有宿主)
|
|
27
|
+
- `npm run build:banner`(**仅当 `docs/screenshots/` 素材有变、需要重出 README banner 时执行**;输入没变时应跳过,否则只会产生 JPEG 重编码噪声。注意该脚本默认 Chrome 路径是写死的 Windows 路径,需用 `PUPPETEER_EXECUTABLE_PATH` 覆盖)
|
|
28
|
+
- `npm run build:lark`(**仅在需要重建飞书 vendor bundle 时执行**。它用当前 esbuild 重新打包 `lib/feishu/lark-bundled.mjs`,产物会随 esbuild 版本漂移;**不要放进 `prepack`**,否则每次 `npm publish` 都会让线上 tarball 里的 vendor 文件与 tag 里的不一致)
|
|
24
29
|
4. **提交**:合并到 `main`(fast-forward),提交信息 `release: vX.Y.Z — ...`
|
|
25
30
|
5. **打 tag**:`git tag vX.Y.Z && git push origin vX.Y.Z`(触发 GitHub Actions 自动创建 Release)
|
|
26
31
|
6. **npm 发布**:`npm publish`(prepack 自动构建产物)
|
package/docs/telegram-usage.md
CHANGED
|
@@ -90,4 +90,4 @@
|
|
|
90
90
|
2. **安全白名单拦截**:
|
|
91
91
|
- 仅白名单内的用户消息会被放行给 Agent;非白名单用户发送的消息会被直接忽略,绝不消耗 Token 或喂给模型。
|
|
92
92
|
3. **敏感操作审批**:
|
|
93
|
-
- 当 Agent 尝试执行系统命令或敏感文件读写时,Telegram 会自动下发 `[✓ 批准执行]` / `[✕ 拒绝执行]` 交互按键,10 分钟未处理自动超时拒绝。
|
|
93
|
+
- 当 Agent 尝试执行系统命令或敏感文件读写时,Telegram 会自动下发 `[✓ 批准执行]` / `[✕ 拒绝执行]` 交互按键,10 分钟未处理自动超时拒绝。
|