Skip to content

Releases: Tongyu3/Tdsh-DSH-Mobile-Android-NO-ROOT

Tdsh 0.4.7

Choose a tag to compare

@Tongyu3 Tongyu3 released this 21 Oct 09:26
fc1fe61

从 0.4.2 之后累积的修复与新增。下载下面的 APK 覆盖安装即可,数据(容器 / 会话 / API Key)都会保留。

0.4.7 — 发热与启动

  • 修复:用久了手机发烫。 悬浮球看护线程原本固定 1.5 秒扫一遍全进程,现在按状态分档(息屏 15 秒 / 前台 4 秒 / 后台 2 秒),进程列表 20 秒才重扫一次,文件读取量下降约 95%。
  • 修复:判白屏时每 5 秒触发一次整页排版。 改用不触发排版的写法;页面正常时 30 秒才量一次。
  • 优化: 页面切后台 / 息屏时不再做主题与按钮定位的定时校准。
  • 修复:插件装多了启动慢。 自带插件改成「本版本装过就真跳过」;启动各阶段耗时写进日志。
  • 新增:手机权限 → 性能体检。 看容器里到底是谁在吃 CPU,明细存 /sdcard/.dsh-phone/perf.txt。
  • 撤掉:容器里的桌宠插件。 显示层早已移除,它只在后台每 100~200ms 写文件、穿过 proot 白烧电。

0.4.6 — 语音、抽屉、输入法

  • 修复(issue #4):语音输入一点录音就报 Could not start audio source。 清单少了 MODIFY_AUDIO_SETTINGS 这条普通权限,装上即生效。
  • 新增(issue #5):手机权限 → 录制屏幕内声音。 过系统确认框后把手机正在播的声音录成 WAV 放进工作区,容器里的 AI 可以直接读;最多 300 秒。
  • 修复:收抽屉像两个抽屉在动、慢半拍。 把 DSH 重新排版内容的时间挪到滑动之后,实测 60 帧无长帧。
  • 修复:点「自动化任务」后抽屉不自动收回。
  • 修复:一切换对话就自己弹输入法。 现在只有点输入框才会弹。
  • 优化: 原生按钮加水波纹;网页按钮去掉安卓默认灰色高亮与那 0.3 秒双击等待。
  • 修复:悬浮球「随任务阶段换表情」从不生效 / 气泡永远停在「空闲」。
  • 修复:明明填了 API Key 却提示不对。 自动清洗零宽字符、全角符号、整句引号;已存的脏 Key 下次启动自愈,不用重装。
  • 撤掉:桌宠的整屏透明浮层。

0.4.5 / 0.4.4

  • 修复: 键盘弹起时输入框不上浮。
  • 修复: 平板上开屏动画被裁掉。

0.4.3

  • 修复: 切到别的应用再回来会出现空白会话页(issue #3)。
  • 修复: 工作区显示成 root,现在显示你手机上的文件夹名。
  • 修复: 悬浮球左右抽动;打开气泡时球闪一下甚至消失。
  • 修复: 输入框黑底、字看不见(浅色主题下)。
  • 修复: 插件「思维链探针」从来不加载。

v0.4.2

Choose a tag to compare

@Tongyu3 Tongyu3 released this 17 Oct 04:22
fc1fe61

"新增:悬浮球换成 9 张表情包贴纸 —— 睡觉 / 大哭 / 委屈 / 惊讶 / 抱鲸鱼 / 无语 / "
+ "开心举手 / 害羞 / 叹气,不规则轮廓直接贴上去(不裁圆、不套蓝圈);"
+ "原来那 4 个纯色球已删除",
"新增:气泡改到球的侧面 —— 尾巴朝侧边指向球,并按左右半区自动翻转"
+ "(球在右半屏气泡去左边,反之亦然);只动位置和尾巴,文字不镜像",
"新增:图标大小、气泡大小各 5 档 —— 都在「悬浮球设置」里,改完立刻生效",
"新增:球会跟着任务阶段换表情 —— 空闲睡觉、起步抱鲸鱼、琢磨时无语、编译叹气、"
+ "干活举手、做完害羞、出错大哭;换的时候有放大 + 轻微旋转的过渡,"
+ "并且 4 秒内最多换一次(不节流的话阶段来回跳,球会一直脉动)。可在设置里关掉",
"新增:「悬浮球设置」独立页面 —— 图标 / 图标大小 / 气泡大小 / 什么时候出现 / "
+ "当前状态 / 完整操作教程。教程原来挤在气泡里,已搬到这里,气泡只留当前步骤一行",
"新增:插件市场支持分类和翻页 —— 一行两个卡片、7 个分类抽屉"
+ "(全部 / 记忆 / 主题皮肤 / 预设 / 界面 / 工具 / 其它)、每页 40 条 + 「加载更多」,"
+ "顶部显示总数(实测 8516 个)。旧版没有翻页,永远只显示 25 条",
"新增:Shell 开关(「手机权限 → 权限相关」)—— 管的是 DSH 能不能执行系统命令、"
+ "读写白名单目录;打开时弹一次确认,并带「用 Shizuku 授权」入口",
"新增:思维链探针插件 —— 提供 thinking_probe / thinking_report / thinking_policy,"
+ "先摸清这台设备上到底哪个接口可写。刻意不给现成开关:上一轮实测证明包 "
+ "llm.stream 这条路是死的,没探明就给开关只会让人以为它在生效(不做假开关)",
"新增:安卓环境预设插件 —— 每轮对话都告诉 agent「你跑在安卓上的 Tdsh 里」、"
+ "有哪些工具、编译环境是什么,省得它按电脑上的路径瞎猜",
"新增:整个 App 跟随 DSH 的主题(白色模式) —— DSH 切浅色,手机权限、插件市场、"
+ "悬浮球设置这些原生页也跟着变浅,状态栏图标自动反色。"
+ "不用系统的深浅开关,跟的是 DSH 自己的主题",
"优化:开屏动画改成真·全屏 + 无缝交接 —— 动画现在盖满整块屏幕(含顶部系统栏区域);"
+ "并且改成「在后台先把页面加载好、收尾播完才揭幕」,"
+ "于是 DSH 自己那圈「Loading plugins…」全程藏在动画底下,不再有等待空窗",
"优化:WebView 预热 —— 启动时先把渲染进程拉起来,等 7.6 秒服务就绪后就能立刻加载,"
+ "省掉渲染进程冷启动的 0.5~1 秒",
"修复:切到别的应用再回来会出现一张空白的会话页,看着像记录全没了(GitHub issue #3)—— "
+ "根因是主界面没设启动模式,点通知栏「正在运行」、换桌面图标进来都会新开一个实例,"
+ "新实例的页面是全新加载的。现在改成全局单实例,回来永远是原来那个会话",
"修复:工作区显示成「root」而不是你手机上的文件夹名 —— 容器里那条路径就是把手机的 "
+ "/sdcard/dsh 挂进去的,DSH 只是照实显示了容器路径的末段。"
+ "现在显示手机侧的真名,对话页顶部和多处列表一起改",
"修复:悬浮球会左右抽动 —— 根因是球的坐标和窗口坐标在来回反推,"
+ "每算一次偏一点点。现在球的坐标是唯一真值、窗口位置由它算出来,重复计算不再产生偏移",
"修复:打开气泡的一瞬间球会闪一下甚至消失 —— 球形态的窗口只有 120px 宽、气泡有 411px,"
+ "放大窗口那一帧球还按旧宽度排在左边,正好被后画的气泡盖住。"
+ "现在改完窗口尺寸立刻同步重排子视图",
"修复:输入框黑底、字看不见 —— 输入框底色原来写死成深色,切浅色主题后底还是黑的。"
+ "现在底色 / 文字 / 提示色 / 选中高亮全部跟随主题(全 App 8 处输入框都已修)",
"撤掉:「实时进度悬浮条」(顶部那个灵动岛胶囊) —— 你确认它是 .wan 版特供,"
+ "正式版去掉入口;代码仍保留在 HudOverlayService,由 .wan 分支接回",
"改动:版本号 0.4.2(第 54 版)"));

v0.4.1

Choose a tag to compare

@Tongyu3 Tongyu3 released this 11 Oct 05:36
fc1fe61

更新说明 · Tdsh 0.4.1(versionCode 53)

起点基线:仓库上一次提交的 0.4.0 / versionCode 52
本次增量:新增 6 · 修改 7 · 删除 1,合计 13 个文件变更,体积 0.59 MB
核对时间:2026-10-10


一、功能

# 变更点 说明(改了什么 / 为什么)
1 新增「删除历史对话」(含已归档) 设置里新增入口,会连已归档的会话一起彻底删除(不是归档);删除前弹二次确认并告知条数,删完自动刷新会话列表。此前用户只能逐个删,已归档的还删不掉。
2 新增 5 个离线自检回归测试 WipeSelfTest / ProcCleanupSelfTest / StoryboardSelfTest / AutoBallSelfTest / BallStageSelfTest。这些被测类都是纯逻辑、不 import android,所以能在电脑上直接跑,用来防止以后改动把删除、进程清理、分镜、悬浮球这几块改坏。
3 新增 Wipe.java(纯逻辑删除工具) 把「删目录树」从 Activity 里抽出来成独立类,才能离线测;支持符号链接识别、失败计数与重新创建空会话目录。

二、修复

# 变更点 说明(改了什么 / 为什么)
4 初始化计时到两位数秒时画面抽一下 根因是顶部状态栏没有宽度约束,「9秒」变「10秒」时文字变长把右侧按钮顶得重新排版。改为按最长文案一次锁死宽度。
5 开屏动画不再被拉伸、也不再有黑边 改为等比覆盖:宽高用同一缩放倍数(不可能变形),底色全幅绘制(不可能留白),超出部分居中裁掉。
6 开屏「点→线→面」生长看不到 一度把加载进度折算进三段生长,外部进度一上报就把线阶段推满、圆点被瞬间跳过。改为生长纯按时间走(点 0.55s → 线 1.00s → 面 1.65s),进度只驱动底部读数。
7 开屏进度条不动 帧号逻辑在重写时丢了「跟真实进度」,且进度只在轮询里每 5 秒上报一次。改为「时间下限保底 + 真实进度取较大值」,并就绪时报满 100%。
8 开屏收尾来不及被看见 原来先让 WebView 可见并载入页面,才想起播收尾,页面一瞬间盖上来。改为:「已就绪」先停 0.5s → 播收尾 → 才交棒页面。
9 开屏动画心跳不停(耗电) 60fps 心跳是 INFINITE 且移除后没人停。新增 stopAnimating() + stopped 标志,收尾结束立刻停。
10 浅色主题下顶部出现「闪光弹」 顶部栏底色被硬编码成深色 SPLASH_BG_DARK,与浅色开屏底色交界处形成刺眼黑边。改为按当前主题取色。
11 开屏首次进界面前后主题不一致 App 外壳此前优先读 DSH 内定主题,导致与手机系统脱钩。按要求改回只跟随手机系统深色开关。
12 用途守卫未彻底移除 「删掉警告插件」只改了构建产物,被构建重新生成覆盖(tools/patch.js 才是源)。已同时修源与产物,并从 APK 内解包核验为 0 处。

三、优化

# 变更点 说明(改了什么 / 为什么)
13 开屏动画整体重做(弃用帧序列,改纯代码绘制) 逐帧播 216 张满分辨率 PNG 导致:主线程同步解码吃满 16ms 帧预算(gfxinfo 27~61ms 约 50 帧)、单帧约 5MB 被系统 OOM kill、光帧序列就 12MB。改为 Canvas 直接绘制后零解码、零额外内存、APK 不再增体积。
14 开屏加四角直角括号 空心圆环 → 空心线条 → 张成矩形 → 中线向两端消失、只留四个直角;线条全部纯白(浅色主题纯黑,DSH 徽标除外),中文用黑体,直角横臂与竖臂等长、整体关于屏幕中心上下对称。
15 开屏收尾改为「倒放一遍」 加载完成后四个直角先重新连成矩形,再压成空心线,最后缩回开始那个点才交棒。文字/读数在收尾前 25% 退干净,不与收缩中的几何重叠(不穿模)。
16 移除开屏上的「设置」按钮 它与进度格重叠、也容易与角上直角混淆;设置入口仍在右上角与 DSH 设置页。相关字段、热区、触摸分支、外部绑定接口一并删除,不留死代码。
17 顶部状态栏宽度锁定 见修复 #4,同时避免后继元素被顶动。

四、资源

# 变更点 说明(改了什么 / 为什么)
18 删除开屏帧序列资源 app/src/main/assets/splash/frames/ 共 216 张 PNG、12.01 MB,改代码绘制后不再需要。APK 由 17.49 MB 降到 5.41 MB。
19 官方鲸鱼标改为运行时反相 官方只提供白色单色标;浅色主题下用 ColorMatrix 反相成黑色,不再额外维护两套位图资源。

五、构建配置

# 变更点 说明(改了什么 / 为什么)
20 versionCode 52 → 53、versionName 0.4.0 → 0.4.1 发布版本号。
21 AndroidManifest.xml 加 android:largeHeap="true" 开屏绘制与 WebView 同时驻留时更容易触发系统内存回收(真机 logcat 抓到过 lowmemorykiller),提高堆上限以稳定运行。
22 tools/patch.js 同步更新 它才是窄屏补丁的源文件(构建时拷成 assets/dsh-mobile.js)。本次从源上删除用途守卫扫描块(1591 字节),并同步产物。

v0.3.2

Choose a tag to compare

@Tongyu3 Tongyu3 released this 04 Oct 09:15
15e29ec

5.1 发 v0.3.2(0.2.8 以来的改动合并成一条)

## v0.3.2

### 新增:虚拟屏自动化(后台跑应用 + 取画面 + 按坐标操作)

**设置 → 手机权限 → 虚拟屏自动化** → 点「一键安装并启动」。

它解决的是"**别占我的屏幕,在后台把某个应用跑起来**":应用跑在一块系统认可的**虚拟屏**上,
不跳屏、不抢前台;DSH 可以取那一块屏的画面(本地通道,毫秒级),也可以按坐标点按。
和"操作手机 App"那套(无障碍、受白名单限制、微信/游戏读不到控件树)是**两条不同的路**。

- 方案与内部两个守护由群友「**如月雨露**」制作,**已随安装包自带**,这一版做了整合与安全加固;
- 装它需要一次 shell 身份:授权 **Shizuku** 后点按钮即可;没有 Shizuku 的话,
  那一页里有现成的 **adb 命令**可以复制执行;
- **手机重启后要重新点一次**(守护的命绑在 adb 调试通道上,这是方案本身的边界);
- 「停止全部守护」会把虚拟屏上跑着的应用一起收掉(系统行为);
- 安全上加了三道:守护**只绑本机回环**(原本绑所有网卡)、**每个请求校验口令**
  (原本零鉴权)、token 与 dex 从共享存储挪到只有系统 shell 能读的目录。

### 新增:容器终端

**设置 → 手机权限 → 容器终端** —— 在手机上直接敲容器里的命令
(`ls -la /root`、`node -v && dsh --version`、`df -h`…),不用插电脑、也不用绕 DSH 对话。
旁边有常用命令,点一下就跑;输出可长按复制。

> 每条命令都是一个独立的容器会话,和正在运行的 DSH 共享同一份文件 ——
> 所以 `npm install` / `dsh plugin add` 这类**会改容器的命令**,建议先把 DSH 停掉再跑。
> 每条命令最多 60 秒,不支持 `vi` / `top` 这种需要真终端的交互式程序。

### 新增:4 张投稿图标(uu27~uu30)

「手机权限 → 桌面图标 → uu们添加的图标」里多了 4 张:**鲸鱼女仆 / 困困女仆 / 举蒲公英 / 端茶女仆**
(群里投稿的图,目前共 30 张)。默认图标不受影响,想换就点一下。

### 修复:输入框里的图片附件,退格键也能删了

以前插进去的图片**只能用缩略图右上角那个 ✕ 删**,按退格键没反应(附件卡片其实在编辑器外面)。
现在:输入框里没有文字时按退格 = 删掉最后一个附件;有文字时照旧删字。

### 撤掉:语音播报(上一版试过,没达到可用标准)

0.3.0 加过语音播报(回复下方「播报」按钮 + 右上角朗读开关 + 系统 / 本地 / 云三种声音来源),
0.3.1 只来得及修了"那个开关会挡住设置页与右侧栏"里的前一半。剩下两条在真机上始终没解决:

- 开关在"右侧栏那个整页面板"打开时仍然不消失(三种判据都试过,都会误伤正常界面 ——
  当时的选择是**不凭猜改**,等拿到同一会话里"关→开"的一对 DOM 快照再定);
- 本地神经语音卡在"从公网拿那 30 MB 引擎"(直连 GitHub 连不上、`ghfast.top` 会卡死)。

所以这一版把它**整块回退**,不再留在界面上:「播报」按钮、右上角朗读开关、
「手机权限 → 语音播报」入口、云语音的设置页,全都没有了;其余功能不受影响。

> 想让它念出来的话:安卓「**设置 → 无障碍**」里的**随选朗读 / 屏幕朗读**
> (不同厂商叫法不一样)选中文字即可,不需要 App 支持。
>
> 从 0.3.0 / 0.3.1 升上来的话,容器里可能残留过 `~/.dsh-voice/`
> (当时下载的本地语音引擎与模型,几十 MB),现在没有任何代码在用它,删掉即可。

### 新增:「中转站」页(接入中转站 / 自部署网关 / Claude 原生接口)

**设置 → 手机权限 → 中转站** → 「+ 添加自定义提供商」,填四样东西:

- **Provider ID**(小写字母开头,例如 `acme-gateway`;它还会派生凭据名 `ACME_GATEWAY_API_KEY`);
- **API 地址**(填到 `…/v1` 即可);
- **API 协议**:OpenAI Chat Completions(绝大多数中转站)/ OpenAI Responses / Anthropic Messages;
- **API 密钥**(只存本机;自部署免鉴权的可以留空)。

然后「**获取可用模型**」一键拉列表(OpenAI 系走 `GET {地址}/models`,
Anthropic 原生走 `GET /v1/models`),能读图的模型点成「文本+图像」,
不认识的先去掉。最后点「**重启 DSH 让它生效**」——重启后这些模型就在
DSH 的**模型选择器**里了。

两条承诺:

1. **密钥不会被写进任何配置文件**:写进 DSH 的只有凭据名这一行,
   真正的密钥由 App 在启动容器时作为环境变量注入;
2. **DSH 网页端自己加的提供方不会被改动**:App 只重写设置里 `llm-pi-ai` 一节里
   属于它自己的条目,写入前备份、写完读回校验,出问题自动回滚。

(这一页的界面灵感来自「小眼睛」,页面上也标了。)

### 0.2.8.4 修的那件事:误判与「显示界面」(上一次的改动在下面)

简单说:自检以前在**整页正文**里找"加载失败"几个字,而这几句会留在聊天记录里,
于是界面本来是好的也被判成"插件卡死"、插件被一个个自动停掉。
0.2.8.4 起只认 DSH 自己的启动画面,点名的插件只停那一个,点名到自带插件时一个都不停,
面板上还多了「**显示界面**」可以直接进去。

### 「安全模式又出问题了」:App 把聊天记录当成了故障现场

有用户反馈:界面明明是好的,App 却弹「界面没能加载出来」,还把插件一个个停掉了;
再进安全模式,插件直接没了、界面反而再也进不去。

原因是老版本的「界面起不来」自检在**整个页面**里找 `Failed to load plugins` /
`did not activate` 这几个字样 —— 而这几句话**会留在聊天记录里**(你把日志贴进过对话、
或者 agent 复述过报错)。于是每次重启进这个会话,自检都命中那段历史消息,
把好端端的界面判成"插件把界面卡死了":自动停用**全部**第三方插件 → 重启 →
聊天记录里那几句话还在 → 再判一次 …… 插件被一个个摘光,界面就真的进不去了。

这一版改了四处:

1. 自检**只认 DSH 自己的启动画面**(页面里那个加载卡)—— 聊天记录里出现同样的字**不再算数**;
2. 认得出 DSH 真正打出来的那句话(`xxx: import failed`)—— 点名到具体插件时**只停那一个**,
   不再"宁可错杀、全部停用";
3. 点名到的是**自带/官方插件**时,**一个都不停**(那种情况停第三方插件帮不上忙,
   只会白白摘掉你自己的插件);
4. 面板上多了一个 **「显示界面」**:觉得 App 判错了就点它,直接进界面,
   本次运行不再自动停插件 —— 不用再卸载重装(那要重下 150MB 容器);
5. 容器没起来时浏览器显示的错误页(连不上、拒绝连接)不会再被当成「界面正常」,
   也不会被算成「插件卡死」。

另外,面板现在会写清楚"这次为什么没动你的插件"(已经全停了 / 点名的是自带插件 /
本来就没有第三方插件),不再笼统地说一句"问题不在插件上";如果插件是写在
`cordis.patch.yml` 里的(DSH 的另一种加载方式),也会明确列出来 ——
那种插件 App 停不了,得自己改那个文件。

**已经中招的:升级后去「DSH 设置 → 手机权限 → 插件安全模式」点「恢复全部」。**
(升级本身不会自动恢复你的插件 —— App 不猜你的意图。)

### 也包含 v0.2.8.3 / 0.2.8.2 / 0.2.8.1 / 0.2.8 的内容(下面几节)

**0.2.8.3**:查清「压缩上下文报 `imageRequestPricing is not a function`」是 DSH 内核的
容错缺口(第三方插件注册的自定义供应商适配器没实现那个可选方法),并给出绕法;
报告里新增「模型路由:<provider>/<model>」一行。

### 0.2.8.3 查清的那件事:压缩上下文报错

报错来自内核:token meter 每个计价请求都会调 `llm.imageRequestPricing(provider, model)`,
而 `dsh-llm` 那行 `this.adapters.get(provider)?.adapter.imageRequestPricing(...)`
只保护了 `get()`、没保护方法本身;DSH 自带的适配器都有这个方法(基类给了空实现),
但**第三方插件注册的自定义供应商适配器**没有 —— 而 `registerAdapter()` 注册时
只校验 `providerInfo` / `providerRetryPolicy`,不校验其余接口,于是就炸在这里。

**绕法**:把压缩/默认模型换回 DSH 自带的供应商(内置 DeepSeek),
或停用提供那个自定义供应商的插件。App 里新增了一行诊断帮你确认:
报告里「模型路由:<provider>/<model>」——provider 不是 `deepseek-official`
基本就是它。(**不是**那个"会在自己端口开面板"的插件干的:它的包里根本没碰适配器。)

### 也包含 0.2.8.2 / 0.2.8.1 / 0.2.8 的内容(下面几节)

**0.2.8.2**:修「装了会自己开服务的插件后,界面变成插件的网页」、
安全模式"插件没了但文件还在"给出文件状态 + 「彻底删除」。

### 0.2.8.2 修掉的两件事

### 装了"会自己开网页服务"的插件之后,整个界面变成了插件的网页

有用户装了 `billion-context` 之后反馈"界面又变成网页了、还是退不出去"。日志里能看到:
那个插件会在**它自己的端口**上起一个面板服务,并把地址打进了 dsh 的输出,
而 App 解析 DSH 地址的规则当时是"看到 127.0.0.1 就抓" —— 于是抓到了插件的端口,
**整个界面被加载成了插件的面板**(那上面没有地址栏也没有后退键,当然退不出去)。

现在只认 DSH 自己的地址(**带鉴权 token 的那个**);插件面板、本地代理这类
"回环但不是 DSH"的地址会被忽略并记进报告。另外"界面不该停在别的本机页面"这条也补严了:
主框架要跳到别的本机服务时交给系统浏览器打开,返回键也会把 DSH 拉回来。

### 安全模式之后"插件没了,但文件还在"

这是预期行为,以前界面没解释过:停用时我们只把 `node_modules/<包名>` **挪到**
`.dsh-disabled/`(所以 DSH 加载不到它),而 **pnpm 的共享商店里还留着一份副本** ——
那是包管理器自己的缓存。

现在「手机权限 → 插件安全模式」会写清楚每个插件的文件在哪,并多了**「彻底删除」**
(连 pnpm 商店里那份一起删)。想留着以后恢复就用「恢复全部」,想彻底不占空间就用「彻底删除」。

### 也包含 0.2.8.1 与 0.2.8 的全部内容(下面两节)

**0.2.8.1**:修掉"某些老手机(系统 WebView 是 Chrome 88~93)界面永远空白" ——
根因是 DSH 前端用了 Chrome 94 才有的语法(class static block),
现在 App 会在传输中把它换成等价写法;同时把页面报错收进运行日志。

**0.2.8**:点开链接交给系统浏览器(不再把界面顶掉)、新增更新日志、
桌面图标多了「uu们添加的图标」分类、老 WebView 会提示去更新。
### 0.2.8.1 的内容(接在上面后面)

### 修掉了一个"界面永远空白"的真凶(用户 HONOR 机器实测)

有位用户的日志很典型:容器 11 项自检**全绿**、`dsh web` 正常、页面也加载完成了,
**界面却一个字都不渲染**。抓下它 served 的前端 bundle 分析后定位到根因:

DSH 主 bundle 里用了 **class static block**(`static{…}`)——那是 **Chrome 94**(2021-09)
才有的语法,而那台机器的系统 WebView 是 **Chrome 88**:**解析阶段**就抛 SyntaxError,
整个 bundle 作废,所以永远是白屏。这种问题补运行时 API 的兼容垫片救不了。

现在 App 会在**传输过程中**把这段语法换成等价写法
(`static{…}` → 静态字段初始化 `static x=(()=>{…})()`,Chrome 72+ 就支持,
求值时机与 `this` 语义都不变),**不修改容器里 DSH 的任何文件**。

| 系统 WebView | 现在的行为 |
| --- | --- |
| ≥ Chrome 94 | 原样加载 |
| Chrome 88 ~ 93 | 自动做语法降级 + 垫片补运行时 API |
| < Chrome 88 | 弹「系统 WebView 太旧」+「去更新」 |

> 说明:**没有**在 Chrome 88 真机上跑过(手头没有那台设备)。
> 三件事是分开钉死的:改写后的文件用 V8 按 ES module 解析通过、
> 改写后的页面在真机浏览器里正常渲染(无 console 报错)、
> 用户日志里那些运行时缺口本来就被垫片补上。

### 顺手:页面报错现在会进运行日志

以后遇到"白屏 / 点了没反应",报告里会多出页面自己报的错:

```
[页面console] Uncaught SyntaxError: Unexpected token '{'  @…/assets/index-….js:7
```

用户点一下「手机权限 → 复制运行日志」就能直接把原因发出来。

### 也包含 0.2.8 的全部内容(下面这一节)

5.2 v0.2.8 的内容(接在上面那段后面一起发)

### 0.2.8 的内容(接在上面后面)

四条都来自用户反馈。

**1. 在 DSH 里点开网页就退不出来了,只能删后台** —— 已修

以前聊天里的链接会在**同一个界面里**把 DSH 顶掉:DSH 没了、注入的分层返回也没了
(那是 DSH 页面里的函数),你面对的是一个没有地址栏、没有后退键的网页,
而返回键只会退出 App。

现在:链接**交给系统浏览器打开**,DSH 界面原地不动,回来看还是刚才的对话。
万一界面还是停在了外部网页上,**按一下返回键直接拉回 DSH**。

**2. 安卓低版本兼容:老机器"首次加载进不去"** —— 现在会告诉你为什么

部分 2019 年前后的机器(比如 iQOO 1)出厂自带的系统 WebView 是 Chrome 6x/7x,
而 DSH 的界面是按现代浏览器打包的,**解析阶段**就读不懂 —— 这种白屏是永远的,
App 内置的兼容补丁救不了(它补的是运行时的 API,不是语法)。

以前这类机器的结局是一轮死循环:页面白 → App 判定"插件卡住" → 停用插件 → 重启 → 还是白。
现在 App 会**先看 WebView 版本**:太旧就直接弹「这台手机的系统 WebView 太旧」,
带上版本号和「去更新」(应用商店 / 系统应用详情页),
并给「仍然重试」「复制日志」两个出口。报告里也带上 WebView 版本,方便排查。

**3. 新增更新日志**

装上新版本后**第一次进界面**,会自动显示这一版改了什么(跨版本升级会把
中间几版一起列出来)。随时想看:**设置 → 手机权限 → 更新日志**。

**4. 桌面图标新增「uu们添加的图标」**

10 张群里 uu 投稿的图打包进了安装包:**设置 → 手机权限 → 桌面图标**,
上面是原来 8 套配色,下面是「uu们添加的图标」。

> Android 不允许 App 用**任意图片**当桌面图标(图标必须是打包进 APK 的资源),
> 所以自己的图没法在手机上现场添加 —— 想加就把图片发给我,下个版本里就有。

v0.2.7

Choose a tag to compare

@Tongyu3 Tongyu3 released this 01 Oct 06:18
c2fc653

一次跨了 17 个版本的更新(0.1.13 ~ 0.2.7)。下面按"你能感觉到什么"来写。

修掉的大问题

1. 用久了白屏、而且进不去(0.2.4)

三种成因,现在都能自己恢复:

  • 界面的渲染进程被系统回收(用久了必然发生,内存一紧张系统就先杀它)→ 自动重建界面;
  • 容器(跑 DSH 的 Linux)被系统清掉 → 自动重新拉起,并自动连到新地址
    (以前只有"切到后台再切回来"才会重连,所以你一直盯着白屏,它就一直白着);
  • 页面自己卡死 → 连续 20 秒页面里一个字都没有,就自动重新加载一次。

实测:App 停在前台时把容器进程直接杀掉,界面自己回来了 —— 不用切后台、不用重开 App。

2. 装了不兼容的插件,界面再也进不去(0.2.2 → 0.2.3 → 0.2.7)

为 DSH 0.1.x 写的插件会一直等一个已经不存在的服务,前端永远停在 pending,
整个界面起不来(典型报错:dsh-speech: pending (waiting for service: settingsScope))。

  • 0.2.2 加了自救面板,把状态栏亮回来并说清原因;
  • 0.2.3 修掉"点了停用其实没停"—— 现在是真的把它从加载列表和依赖里摘掉、
    并把包目录整个挪走,所以不可能再被加载;
  • 0.2.7 变成全自动:界面第一次起不来,App 就自己把可疑插件停掉并重启,
    你什么都不用点。之后可以在「手机权限 → 插件安全模式」里一键恢复。

自动动手最多 2 次:如果根本不是插件的问题(容器/网络),"停用+重启"救不回来,
不能无限重启下去(否则界面一直闪、插件还一个个消失),超过就停下来把选择权交回给你。

3. 选完文件 / 图片,回到界面什么都没加上(0.2.4 / 0.2.5)

各家相册返回的文件地址格式不一样;更麻烦的是真正去读它的是界面的渲染进程,
而厂商的「安全访问」、云盘给出的地址往往只有主进程能读 ——
界面读不到内容时不会报错,它只是当作用户什么都没选,看起来就是"点了没反应"。

现在改成:一律先把内容复制进 App 自己的缓存,再把这份副本交给界面。
图片、视频、音频、文档,从哪个入口选都一样。

4. 平板用户找不到设置、也找不到会话(0.2.4 / 0.2.6)

  • 「手机权限」「API Key」这两个入口以前只在窄屏注入 → 平板上根本没有入口进白名单;
  • 平板竖屏(约 800dp 这一档)DSH 只显示一条图标轨道、会话列表压根没有渲染 →
    现在打开就是完整侧边栏(新会话 / 插件 / 工作区 + 会话列表 / 设置)。

5. 新版环境装不上,或者拿着装到一半的坏容器反复重试(0.2.1)

下载会校验字节数、解压后核对关键文件(缺一个就丢掉重下),
空间不够会直接告诉你要腾多少 —— 以前那种"装不上、点重试也没用"的死循环就是这么来的。

6. 首次启动永久卡死 / dsh web 起不来(0.1.5 / 0.1.7 / 0.1.8)

补了超时、端口冲突自动换端口、失败原因不再被最后一行日志盖掉;
npm install 失败会保留最后 40 行输出、报错行实时显示、自动重试 3 次(第 3 次改用官方源)。

7. 老手机上"进了界面却用不了"(0.1.9)

系统 WebView 低于 Chrome 116 时界面能开,但一直「未连接」、工作区列表空转。
根因是兼容垫片因为注入语句漏写了一个变量,从来没有真正生效过 —— 两处都修了,
并补上对照实验(先删掉这些 API 复现故障,再确认垫片能补回来)。

8. 白名单计数与实际不符(0.2.1)

有些应用(最典型的是荣耀桌面这类桌面应用)不响应桌面的应用查询,以前会被列表过滤掉 ——
它还在白名单里(计数里有它),但你看不到也取消不掉。现在每一项都一定在列表里。

新能力

  • 手机控制插件化 + 插件市场(0.1.13):agent 现在能截图(微信这类屏蔽控件树的应用靠它)、
    能用内置输入法往里打字;手机控制做成了 DSH 原生插件 dsh-phone(10 个工具),
    并加了插件市场,可以直接在手机上搜索安装社区插件。
  • 无障碍守护 + Shizuku 授权(0.1.10 / 0.1.11):vivo / iQOO 会在 QQ、微信切前台时
    偷偷把无障碍开关置 0,现在 App 会自己写回(实测约 0.3 秒恢复,无次数上限)。
    没有电脑的用户可以走 Shizuku 完成那一次授权(全程在手机上,不需要电脑也不需要 root)。
    另外可以切「直接命令」后端(uiautomator + input),不依赖无障碍,不受厂商策略影响。
  • 手机文件插件(0.2.3):DSH 右侧栏新增「手机文件」标签页 ——
    像文件管理器一样浏览手机存储,多选后一键把路径加进会话。只读,不删改你的文件。
  • 一键复制运行日志(0.2.5):「手机权限 → 复制运行日志」,出问题点一下就能发给开发者。
  • 内核一键升级(0.1.18):在手机上检测并升级容器里的 DSH。
  • 常驻服务(0.1.17):给 CLIProxyAPI 这类本地代理配自启 + 挂了自动重拉。
  • 桌面图标 + 通知图标配色(0.1.19):8 套可选,通知栏图标跟着一起换。
  • 设置界面重做(0.1.20):收成「API Key」+「手机权限」两项,带线条图标,
    去掉一堆解释性小字。
  • 启动更快(0.1.16):冷启动 16.5 秒 → 10.1 秒。
  • 地区镜像可选(0.2.1):首次启动选「中国大陆 / 非中国大陆」,
    用阿里云 / 中科大或官方源,装环境不再慢到怀疑人生;随时能在设置里改。

界面与交互修复

侧边栏会话条目单击即可切换、右侧「…」菜单常显(0.1.21)|返回键分层返回
(0.1.17 / 0.1.21 / 0.2.0)|想归档不再被迫先切走一次会话(0.1.14)|
图片预览能看全、「打开方式」真正交给安卓(0.1.15)|输入法打完字自动切回(0.1.16)|
鲸鱼按钮唤出侧边栏、插件页抽屉自动收回(0.1.21 / 0.2.0)。

已知限制(重要)

  • QQ / 微信的界面读不出来。实测这两个 App 对 uiautomator 和无障碍
    两条路都返回空树(微信只有 407 字节的根节点),是它们自己屏蔽的,不是本 App 的问题。
    其他 App 不受影响。
  • 只能侧载,永远无法上架 Google Play:targetSdk 固定 28 是硬要求
    (Android 10+ 的 W^X 禁止 targetSdk≥29 的应用执行自己数据目录里的二进制)。
  • 仅 arm64、Android 7.0+;首次启动需要联网约 150 MB,并自备 DeepSeek API Key。
  • 装第三方插件有风险:与当前 DSH 不兼容的插件会让界面起不来
    (App 会自动兜住并恢复,但仍建议装之前看一眼 docs/第三方插件清单.md)。

升级提示

同签名,直接覆盖安装即可。容器(约 150 MB,已经下好的 Ubuntu + Node + DSH)、
API Key、白名单、会话记录都不会丢。

v0.1.12

Choose a tag to compare

@Tongyu3 Tongyu3 released this 28 Sep 04:00
4b09ea9

修掉的大问题

1. 老手机上"进了界面却用不了"(0.1.9)

系统 WebView 低于 Chrome 116 时,界面能打开,但一直显示**「未连接」**、
选工作区一直转圈「正在加载工作区…」。

根因有两层:

  • 兼容垫片 webview-shim.js 因为注入语句漏写了一个变量,从来没有真正生效过
    —— 文件在仓库里、编译无警告、日志无异常,只有老机器上症状照旧;
  • 垫片本身也确实缺 AbortSignal.any(需要 Chrome 116+)。

两处都修好了,并补上了对照实验(先删掉这些 API 复现故障,再确认垫片能补回来)。

2. 首次启动永久卡死 / dsh web 起不来(0.1.5、0.1.7)

卡在"正在重启容器内的 DSH…"和"初始化失败"的问题:补了超时、端口冲突时自动换端口、
失败原因不再被最后一行日志覆盖掉。

3. npm 装不上,只给一个退出码(0.1.8)

现在会保留 npm 的最后 40 行输出、报错行实时显示、失败自动重试 3 次
(第 3 次改用官方源),并自动区分"是 Node 坏了"还是"是下载坏了"。

新能力

无障碍守护(0.1.10)

vivo / iQOO 会在 QQ、微信切到前台时把无障碍开关自动置 0。
现在 App 会自己把它写回去 —— 实测约 0.3 秒恢复,没有次数上限。
(实测连续 50 次清零,50/50 全部接住。)

需要一次授权,之后永久有效(重启手机、更新 App 都不会掉):

adb shell pm grant com.dshmobile.probe android.permission.WRITE_SECURE_SETTINGS

Shizuku 支持(0.1.10)

没有电脑的用户可以走 Shizuku 完成上面那次授权,全程在手机上,
不需要电脑也不需要 root。详见 docs/Shizuku授权教程.md。

说明一下边界:任何 APK 都不可能"自带最高权限" ——
Shizuku 的权限来自 ADB 或 root,是从应用外部拿进来的。
我们能做的是把这一步压成"一次动作、永久有效"。

两种操作后端可切换(0.1.11)

设置 → 📱 手机控制里可以选:

  • 无障碍(默认):快,但可能被厂商策略关掉(会自动补回)
  • 直接命令:用 uiautomator + input 绕开无障碍,但读界面慢、只能输英文数字

白名单边界两条路都一样严格:不在名单里的应用,读界面和点击都会被拒绝。

平板支持(0.1.9)

手机和平板共用同一个包。之前宽屏会跳过一部分界面优化(比如回车变成直接发送),
现在跟屏幕宽度无关的优化全都通用;平板本来就该有的常驻侧边栏、双栏设置保持原样。

界面修复

回车改成换行(发送只靠按钮)、侧边栏动画不再抖、设置页不再闪一下"通用设置"、
附件上传打通(拉起系统文件管理器)、落地页多余的侧边栏按钮去掉。

已知限制(重要)

QQ / 微信的界面读不出来。 实测这两个 App 对 uiautomator 和无障碍
两条路都返回空树(微信只有 407 字节的根节点),是它们自己屏蔽的,不是本 App 的问题。
所以这两个 App 目前无法自动化,其他 App 不受影响。

其余限制见仓库 README 的「限制」一节。

v0.1.8

Choose a tag to compare

@Tongyu3 Tongyu3 released this 27 Sep 03:56
79316de

改进安装失败的诊断:保留 npm 完整输出、报错实时显示、失败自动重试 3 次并更换源、额外跑 node 自检区分"Node 坏了"还是"下载坏了"

0.1.7

Choose a tag to compare

@Tongyu3 Tongyu3 released this 27 Sep 03:21
79316de

修复:容器装好了但界面一直"初始化失败"

上个版本虽然解决了卡死,但如果 3080 端口被别的进程占用,
dsh web 会绑不上端口并无限重启 —— 现象和"卡死"一模一样,且看不到原因。

本版:

  • 端口自动避让:3080 被占用时自动改用 3081~3090
  • 保留 dsh 的输出:失败时在屏幕上直接显示服务状态、实际端口和 dsh 最后几行输出
  • 修复失败原因被覆盖:之前失败提示会被日志刷新擦掉,只剩"初始化失败"四个字
  • 快速识别"前台服务被系统拦截"(20 秒内给出提示,不再白等 4 分钟)
  • 回到前台时自动跟随容器地址变化

v0.1.6

Choose a tag to compare

@Tongyu3 Tongyu3 released this 27 Sep 03:08
fae595b

修复:部分老手机打开就报 Failed to load plugins

如果界面起不来、只显示:

Failed to load plugins
failed to import loader entry ... : Iterator is not defined

说明你的系统 WebView 太旧。本版内置了兼容垫片,补齐了 13 类现代 JS API
(Iterator、URL.parse、Promise.withResolvers、Object.groupBy、Set 集合运算…),
装上即可正常使用。垫片是幂等的能力检测,新手机不受影响。

修复:首次使用会永久卡在「正在重启容器内的 DSH…」

这是上个版本最严重的问题 —— 别人装好后一直停在那一句话上,只能卸载重装。
根因是容器命令没有任何超时(npm install 一卡就永远等下去),
下载也没有总时长上限,初始化失败后没有任何恢复入口。

现在:

  • 所有耗时命令加超时 + 心跳(npm 25 分钟 / 5 分钟无输出即判卡死)
  • 界面显示下载进度与已耗时,一眼区分"在跑"和"卡死"
  • 顶部新增 「重试」(长按 = 清空容器重新初始化)
  • 容器没装好时不再弹出阻塞式对话框打断初始化
  • 新增 「复制日志」,出问题可一键复制发出来

其它

  • 回车现在换行,发送请点右下角发送按钮(0.1.3)
  • 修复打开设置时闪现「通用设置」详情页(0.1.3)
  • 签名增加 v3 方案,提升安装兼容性
  • 详见 CHANGELOG.md

安装

下载下方 DeepSeek-Harness-0.1.6.apk,传到手机点击安装。
首次启动会联网下载约 150MB 运行环境,需要自备 DeepSeek API Key。
仅支持 arm64 + Android 7.0 以上。

同签名,可以直接覆盖安装,不会清空容器、API Key 和白名单。

v0.1.3

Choose a tag to compare

@Tongyu3 Tongyu3 released this 26 Sep 12:53
fae595b
  • 回车现在是换行,发送请用右下角发送按钮
  • 修复打开设置时闪现「通用设置」详情页
  • 修复附件上传(点「+」拉起系统文件管理器)
  • 修复侧边栏/设置页动画与层级问题
  • APK 体积 2.43 MB → 1.69 MB