dsh-plugin-tether 0.1.22 → 0.1.24
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 +35 -0
- package/index.js +23 -4
- package/package.json +7 -7
package/CHANGELOG.md
CHANGED
|
@@ -2,6 +2,41 @@
|
|
|
2
2
|
|
|
3
3
|
本文件记录面向用户的变化。每个版本的这一节会原样作为该版本 Release 的说明。
|
|
4
4
|
|
|
5
|
+
## 0.1.24
|
|
6
|
+
|
|
7
|
+
### 修复
|
|
8
|
+
|
|
9
|
+
- **老 WebView 上 dsh 界面整个起不来:停在「正在加载工作区…」,或点「选择工作区」时报 `AbortSignal.any is not a function`**([#20](https://github.com/zexadev/dsh-tether/issues/20))。dsh 0.2.1-rc 的前端用到 `Promise.withResolvers`(Chrome 119 起有)和 `AbortSignal.any`(Chrome 116 起有),而华为等厂商随系统发的 WebView 还停在 Chromium 114,两个都没有。前者让启动脚本当场抛错,后者让读取远端数据那一步次次失败,界面于是无限转圈重连。现在 App 在建窗口时就补上这两个 API,并且补进页面里内嵌的 dsh 界面那一层——它和外壳不同源,只补外壳够不着。补之前先探测,WebView 自带的就不动,新机器上等于没有这段代码。真机对照:华为 TET-AN50 / Android 12 / WebView 114.0.5.302,修前必现,修后 dsh 正常启动、目录列表正常、脚本报错为零;本机模式与终端不受影响。
|
|
10
|
+
- **放一段时间后界面卡在「重新连接中」,等多久都不恢复,只能强停 App 重开**([#19](https://github.com/zexadev/dsh-tether/issues/19))。四处缺陷叠在一起:
|
|
11
|
+
- 链路死了也不报断开。读写两侧用「都结束才算完」来等,而写侧平时一直阻塞在待发队列上、只有读侧会报错,这个条件于是永远不成立。实测杀掉电脑侧 sidecar 七分钟,手机顶栏一直显示「已连接」,一条断开事件都没发出来。改成任一侧结束即收尾,现在约半分钟内就会报「连接已断开」并给出「重新连接」。
|
|
12
|
+
- 本地代理的监听口既不随连接关闭,换连接时也不让出。按主机派生的那个固定端口因此被废弃的监听长期占着,新连接只能退回随机端口。更要命的是废监听照样接受 TCP 连接、但每个请求都被丢掉——页面看着是连上的,实际一个请求也出不去,这正是「显示正常却一直重连」的来由。
|
|
13
|
+
- 端口一换,对 dsh 来说就是换了个来源,按来源存的状态(当前会话、界面偏好)全是空的,于是每次重连都像第一次打开。
|
|
14
|
+
- 旧连接收尾时不看自己还是不是当前那条,一律广播断开并清空发送端。刚建好的新连接会被它一起判死:顶栏在连上的同一毫秒跳回「未连接」,审批决定也发不出去。
|
|
15
|
+
|
|
16
|
+
真机验证:杀掉电脑侧进程后 37 秒内报断开;重连回到同一个固定端口;连按三次重连,手机上始终只有那一个监听口,也不再出现多余的断开事件。
|
|
17
|
+
- **会话里工具调用那几行被切掉大半,只剩文字最上面一道横杠**([#18](https://github.com/zexadev/dsh-tether/issues/18))。这是 0.1.0 起给窄屏注入的样式写宽了:那条规则本来只给设置弹窗的「说明 + 控件」行用,判据却只看类名里带不带 `row`,把会话里的工具调用行一并命中了。那种行高度写死、超出即裁,被强行允许换行之后图标占满第一行、标题掉到第二行,露在外面的只剩第二行最上面几个像素。文件路径、命令、报错这类长标题全中招,短标题排得下反而没事,所以一问一答看不出来、任务一跑长就满屏横杠。判据改成「这一行里确实有说明列」:设置弹窗照旧,会话里的行恢复单行加省略号。顺带说明,这跟手机型号和 WebView 版本都没关系——把桌面浏览器窗口收到同样宽度,一样会出现。
|
|
18
|
+
|
|
19
|
+
### English
|
|
20
|
+
|
|
21
|
+
The whole dsh interface failed to start on older WebViews: it sat at "Loading workspace…", or choosing a workspace reported `AbortSignal.any is not a function` ([#20](https://github.com/zexadev/dsh-tether/issues/20)). The dsh 0.2.1-rc frontend uses `Promise.withResolvers` (Chrome 119 and later) and `AbortSignal.any` (Chrome 116 and later), and the system WebView shipped by Huawei and others is still on Chromium 114, which has neither. The first made the boot script throw outright; the second made every read of remote data fail, so the client looped on "connection lost, retry". The app now supplies both APIs when it creates the window, including inside the embedded dsh interface — that frame has a different origin, so patching the shell alone never reaches it. Each API is feature-detected first and left alone when the WebView already has it, so on a current device this code does nothing. Checked on a real device, Huawei TET-AN50 / Android 12 / WebView 114.0.5.302: the failure was reproducible before and gone after, with dsh starting, the directory list rendering, and no script errors. Local mode and the terminal are unaffected.
|
|
22
|
+
|
|
23
|
+
After sitting idle the interface got stuck on "Reconnecting", never recovered however long you waited, and only a force stop brought it back ([#19](https://github.com/zexadev/dsh-tether/issues/19)). Four defects stacked up. First, a dead link was never reported: the connection waited for both its reader and its writer to finish, and the writer normally blocks forever on the outgoing queue while only the reader errors out, so that condition never came true — with the computer-side sidecar killed, the phone kept showing "Connected" for seven minutes without emitting a single disconnect. Either side finishing now ends the connection, so the disconnect and the Reconnect button appear within about half a minute. Second, the local proxy listener was neither closed when its connection ended nor released when a new connection replaced it, so the port derived from the computer stayed occupied by a dead listener and every later connection fell back to a random one — and the dead listener still accepted TCP while dropping every request, which is exactly how the page can look connected while nothing gets through. Third, once the port changes dsh sees a different origin, so everything stored per origin (the current session, interface preferences) comes up empty and every reconnect looks like a first run. Fourth, a connection tearing down did not check whether it was still the current one, and broadcast a disconnect and cleared the send channel regardless, killing a connection that had just been established: the status flipped back to "Not connected" in the same millisecond it connected, and approval decisions could no longer be sent. Verified on a real device: the disconnect now arrives 37 seconds after the computer-side process is killed, a reconnect returns to the same derived port, and three reconnects in a row leave exactly one listener on the phone with no spurious disconnects.
|
|
24
|
+
|
|
25
|
+
Tool-call rows in a conversation were sliced down to a sliver of their top edge ([#18](https://github.com/zexadev/dsh-tether/issues/18)). The narrow-screen styling injected since 0.1.0 was written too broadly: the rule was meant for the "description plus control" rows of the settings dialog, but it matched on nothing more than the word `row` in a class name, so it also caught the tool-call rows in the conversation. Those rows have a fixed height and clip their overflow, so once wrapping was forced on them the icon filled the first line, the title dropped to a second line, and only a few pixels of that second line stayed visible. Long titles — file paths, commands, error messages — all hit this, while short ones still fitted on one line, which is why a single question and answer looked fine and a longer task filled the screen with slivers. The rule now requires the row to actually contain a description column: the settings dialog is unchanged, and conversation rows are back to one line with an ellipsis. For the record, this had nothing to do with the phone model or the WebView version — narrowing a desktop browser window to the same width reproduces it.
|
|
26
|
+
|
|
27
|
+
## 0.1.23
|
|
28
|
+
|
|
29
|
+
### 修复
|
|
30
|
+
|
|
31
|
+
- **登录账号后,侧栏里「连接手机」四个字竖成一列、后面顶着一个灰圆**([#17](https://github.com/zexadev/dsh-tether/issues/17))。0.1.22 起这个按钮改抄侧栏底部那一行的样式,抄文字样式时取的是那一行里的第一个文字块:没登录时它正好是文字,登录之后那一行最前面多了头像,抄来的就成了头像的样式 —— 一个 24 像素宽的圆形色块,四个汉字塞进去只能一字一行。现在改抄那一行里最末尾的纯文字块,并且那一行每次换形态(登录、退出、侧栏收放)都重新挑一次。dsh 0.2.1-rc 的浏览器界面登录后同样会这样,一并修了。按钮本身一直能点,配对不受影响。
|
|
32
|
+
- **侧栏收成竖条时,「连接手机」的文字还挤在图标旁边**。dsh 自己那一行在竖条态只画图标、不画文字,我们没跟着收。现在参照的那一行不显示文字时,按钮也只留图标;按钮的无障碍名称一直都在,读屏不受影响。
|
|
33
|
+
|
|
34
|
+
### English
|
|
35
|
+
|
|
36
|
+
Signed in, the Connect a phone label in the sidebar stacked one character per line with a grey circle behind it ([#17](https://github.com/zexadev/dsh-tether/issues/17)). Since 0.1.22 the button copies the styling of the row at the bottom of the sidebar, and it picked the first text block in that row to copy from. Signed out that block is the label; signed in the row gains an avatar in front, so the button copied the avatar's styling instead — a round 24-pixel swatch, which a four-character label can only enter one character at a time. The button now copies the last plain-text block in that row, and picks it again every time the row changes shape (signing in or out, collapsing or expanding the sidebar). The browser interface of dsh 0.2.1-rc did the same thing once signed in, and is fixed as well. The button itself always worked, and pairing was never affected.
|
|
37
|
+
|
|
38
|
+
With the sidebar collapsed to a strip, the Connect a phone label was still crammed next to the icon. The dsh row above it draws only its icon in that state, and the button did not follow. The button now drops its label whenever the row it copies has none; its accessible name stays in place, so screen readers are unaffected.
|
|
39
|
+
|
|
5
40
|
## 0.1.22
|
|
6
41
|
|
|
7
42
|
### 修复
|
package/index.js
CHANGED
|
@@ -455,9 +455,11 @@ const tetherCss = `
|
|
|
455
455
|
/* 设置行是「说明文字 + 控件」一行排开,说明列 min-width:0,窄屏被控件挤到
|
|
456
456
|
2px 宽,中文于是一字一行。让说明占满一行、控件换到下一行。
|
|
457
457
|
选择器咬的是 CSS Module 的本地名(row/rowText),只有哈希前缀会随构建变;
|
|
458
|
-
dsh 若重命名,规则失效退回现状,不会更糟。
|
|
459
|
-
|
|
460
|
-
|
|
458
|
+
dsh 若重命名,规则失效退回现状,不会更糟。
|
|
459
|
+
必须要求带 rowText 直接子元素:光凭名字里有 row 还会命中会话里的工具调用
|
|
460
|
+
行,那种行高度写死 24px 且 overflow:hidden,一换行标题就被切掉半截。 */
|
|
461
|
+
[class*="_row"]:has(> [class*="rowText"]) { flex-wrap: wrap !important; }
|
|
462
|
+
[class*="_row"] > [class*="rowText"] { flex: 1 1 100% !important; }
|
|
461
463
|
|
|
462
464
|
/* 弹窗是「左导航 + 右内容」横向排列,导航固定 188px——在 412px 的手机上
|
|
463
465
|
占掉 45%,内容只剩两百出头。改成导航横排在顶、内容占满整宽。
|
|
@@ -772,6 +774,20 @@ const tetherScript = `
|
|
|
772
774
|
return width >= 12 && width <= 24 ? width : 16
|
|
773
775
|
}
|
|
774
776
|
|
|
777
|
+
// 参照行里装文字的那个 span。登录后账号行是「头像 span + 文字 span」两个,头像那个
|
|
778
|
+
// 24×24、圆、带 skeleton 底色,抄到它中文就竖成一字一行;头像恒在文字前面,所以取
|
|
779
|
+
// 末位。判据是「里面没有元素、不带 data-avatar-status」,不认类名 —— 类名带内容哈希。
|
|
780
|
+
// 侧栏收起时那一行只有图标、没有文字 span,返回 null。
|
|
781
|
+
function referenceLabelOf(trigger) {
|
|
782
|
+
var spans = trigger.querySelectorAll('span')
|
|
783
|
+
var picked = null
|
|
784
|
+
for (var i = 0; i < spans.length; i++) {
|
|
785
|
+
var span = spans[i]
|
|
786
|
+
if (span.children.length === 0 && !span.hasAttribute('data-avatar-status')) picked = span
|
|
787
|
+
}
|
|
788
|
+
return picked
|
|
789
|
+
}
|
|
790
|
+
|
|
775
791
|
// dsh 自己那套小图标的画法:16 视图框、1.3px 描边,字形落在 1.5~14.5 的方框里
|
|
776
792
|
function phoneIcon(size) {
|
|
777
793
|
return '<svg width="' + size + '" height="' + size + '" viewBox="0 0 16 16" fill="none" stroke="currentColor" stroke-width="1.3" aria-hidden="true">'
|
|
@@ -804,13 +820,16 @@ const tetherScript = `
|
|
|
804
820
|
ensureFallbackStyle()
|
|
805
821
|
} else {
|
|
806
822
|
var labelSpan = button.querySelector('[data-dsh-tether="hosts-label"]')
|
|
807
|
-
var referenceLabel = reference.trigger.querySelector('span')
|
|
808
823
|
// 类名带内容哈希,照抄参照行当前的,外观自然跟随 dsh 自己的构建。侧栏收起/
|
|
809
824
|
// 展开、登录状态变化时它会换类名,也会换图标尺寸,跟着同步
|
|
810
825
|
var sync = function () {
|
|
811
826
|
row.className = reference.row.className
|
|
812
827
|
button.className = reference.trigger.className
|
|
813
828
|
if (reference.browser) return
|
|
829
|
+
// 参照行换形态时文字 span 会换一个节点(登录后前面多出头像),每次重挑
|
|
830
|
+
var referenceLabel = referenceLabelOf(reference.trigger)
|
|
831
|
+
// 侧栏收成竖条时参照行干脆不渲染文字,我们的文字也跟着收掉
|
|
832
|
+
labelSpan.style.display = referenceLabel ? '' : 'none'
|
|
814
833
|
if (referenceLabel) labelSpan.className = referenceLabel.className
|
|
815
834
|
// 账号行的形态写在自己的 data-* 上(没登录 32px 矮一截,收起时 36×36 居中),
|
|
816
835
|
// 光抄类名只拿到组件的默认形态,会比隔壁高一截。属性名按前缀抄,不写死是哪几个
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "dsh-plugin-tether",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.24",
|
|
4
4
|
"description": "Mobile client for the DeepSeek Harness — use the dsh on your dev machine from your Android or iOS phone, remotely across networks, peer-to-peer over iroh with no server to set up (falls back to a relay that only sees ciphertext)",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"dsh",
|
|
@@ -56,11 +56,11 @@
|
|
|
56
56
|
"@deepseek-ai/dsh-user-approval": { "optional": true }
|
|
57
57
|
},
|
|
58
58
|
"optionalDependencies": {
|
|
59
|
-
"dsh-tether-host-android-arm64": "0.1.
|
|
60
|
-
"dsh-tether-host-darwin-arm64": "0.1.
|
|
61
|
-
"dsh-tether-host-darwin-x64": "0.1.
|
|
62
|
-
"dsh-tether-host-linux-arm64": "0.1.
|
|
63
|
-
"dsh-tether-host-linux-x64": "0.1.
|
|
64
|
-
"dsh-tether-host-win32-x64": "0.1.
|
|
59
|
+
"dsh-tether-host-android-arm64": "0.1.24",
|
|
60
|
+
"dsh-tether-host-darwin-arm64": "0.1.24",
|
|
61
|
+
"dsh-tether-host-darwin-x64": "0.1.24",
|
|
62
|
+
"dsh-tether-host-linux-arm64": "0.1.24",
|
|
63
|
+
"dsh-tether-host-linux-x64": "0.1.24",
|
|
64
|
+
"dsh-tether-host-win32-x64": "0.1.24"
|
|
65
65
|
}
|
|
66
66
|
}
|