Releases: qiannianhuanxiang/DSHA
Release list
DSHA v1.1.9-rc2
仅支持 arm64 / Android 8.0+,APK 已内置完整 Linux 环境。
versionName 1.1.9-rc2
versionCode 93
sha256 ff6e6847e4ba0cc69c9e5d10baf1a049fdb84d9478f5004db4f8f6b33afc9fc8
由 CI 构建并用项目 release keystore 签名,可直接覆盖安装。
以下是自动生成的变更记录:
Full Changelog: v1.1.9-rc1...v1.1.9-rc2
DSHA v1.1.9-rc1
仅支持 arm64 / Android 8.0+,APK 已内置完整 Linux 环境。
versionName 1.1.9-rc1
versionCode 92
sha256 6e3af0344b093faa17c76f53686f158ab74844454326253818f4fe925a3f833e
由 CI 构建并用项目 release keystore 签名,可直接覆盖安装。
以下是自动生成的变更记录:
Full Changelog: v1.1.8...v1.1.9-rc1
DSHA v1.1.8
仅支持 arm64 / Android 8.0+,APK 已内置完整 Linux 环境。
versionName 1.1.8
versionCode 91
sha256 4ce82bfbab9a07e83c96bcb9277d06c97275fb94696a251f039c03153a2c109e
由 CI 构建并用项目 release keystore 签名,可直接覆盖安装。
以下是自动生成的变更记录:
What's Changed
- fix: 自动恢复弹窗永远不出现——判据被解压步骤挡死 + 分区存储下扫描恒为 0 (#32) by @cwen63970-coder in #33
New Contributors
- @cwen63970-coder made their first contribution in #33
Full Changelog: v1.1.7...v1.1.8
DSHA v1.1.7
仅支持 arm64 / Android 8.0+,APK 已内置完整 Linux 环境,可直接覆盖安装。
versionName 1.1.7
versionCode 85
sha256 a0dd356b608595b8e8355f8b5628c8657e28b257321d216cdb2e3bbbe6788e5e
🔐 升级后第一件事:授予「所有文件访问」
这一版把对话数据搬出了 App 私有目录,从此卸载 App 或换机重装都不会丢。
进入 App 会自动弹窗申请权限并说明用途,点「去开启」即可。开完返回 App 会立刻迁移已有会话,不用等下次启动。
内部存储/Documents/dshdata/
├── sessions/ 对话记录
├── storages/ 插件与工具的持久数据
├── attachments/ 附件
└── settings.yaml dsh 设置
原位置留符号链接,dsh 侧完全无感。这几个目录在文件管理器里直接可见,也可以自己复制走做备份。
不开也能正常用,但数据只存在 App 私有目录里,卸载即丢失。想确认当前状态,到「设置」页跑一次自检,看新增的「对话数据存放位置」这一项 —— 它会明确告诉你现在到底会不会丢。之前这个迁移在缺权限时会静默跳过,用户以为安全了其实没有。
刻意留在私有目录的东西:.credentials.yaml(公开区无法保证 660 权限,密钥会暴露给其他 App)、DSH_HOME 本体与 plugins(dsh 用符号链接维护 node_modules,而公开目录的 FUSE 文件系统禁止软链)。
API Key 改用 Android Keystore 加密(AES/CBC,随机 IV,密钥不出 Keystore)。旧的明文 key 首次读取时自动转成密文并清掉原值;备份里的那份也加密后再写 —— 此前是明文进 Download/DSHA。
🐛 修复
每条 agent 命令都弹危险确认
危险 Shell 守卫会给每条命令包一层 source /root/dsh-guard.sh 2>/dev/null; —— 这个前缀里的 > 让「覆盖关键路径」那条判据恒为真。于是 agent 只要提到 /root/.dsh、/usr/local/bin、/etc/ 就要你确认一次,而干活时提到这些路径极其常见。
判危前先剥掉自己注入的前缀。顺带修了三处误伤:裸词改整词匹配(eval 不再命中 evaluate、format 不再命中 formatBytes)、混淆检测不再误判 echo 'a' 'b'、>> 追加不算清空。用 22 条真实命令验过:12 条正常命令零误拦,10 条危险命令全部拦住。
深色模式按钮浅蓝底浅字,看不清写了什么
Material3 主题会把布局里的 <Button> 自动膨胀成 MaterialButton,而它默认用 colorPrimary 填充背景、直接忽略 android:background。深色模式下就是浅蓝底(#7DA7F4)配浅灰字(#A6B0C3),对比度约 1.3:1,远低于可读线。影响启动页的重启/停止、设置页的 ADB 全部按钮等 12 处。
插件安装莫名失败
「包不存在」的判据过宽,ENOTFOUND、裸 404 这类网络抖动都被当成包不存在,于是自动回退到 git 源,而 pnpm ≥ 11 拒绝执行 prepare 脚本,变成必然失败。现在只认 registry 明确说没有;网络故障换镜像重试同一个包,不换机制;能识别「只能从 registry 装」的硬信号(workspace:* 依赖、scripts.prepare、bundledDependencies)并自动改用 npm 包名。安装前还会做一次预检,失败时告诉你试过哪几条路、各自为什么不行。
插件市场「筛选」按钮点了没反应 —— 它从来没被绑定过监听。
✨ 改进
插件市场筛选 接入市场源自带的分类(技能包、工具…),可按分类、兼容性、是否已安装筛选。分类列表从市场内容动态提取,上游新增分类会自动跟上。
界面
底栏 启动 · 插件 · 设置 · 终端(按使用频率重排)
图标 插件换成拼图、设置换成标准齿轮(旧图标坐标越界,渲染后是扭曲的)
链接栏 GitHub 插件链接解析移到顶部标题栏,插件页内容整体上移
配置页 「接入」卡片改叫「API Key」,端口收进「▸ 高级」折叠区
模型与沙箱权限模式移除(WebUI 设置里改,避免两处都能改却不知哪个生效)
由 GitHub Actions 构建并用项目 release keystore 签名。校验:
sha256sum -c deepseekharness-arm64-v1.1.7.apk.sha256Full Changelog: v1.1.6...v1.1.7
DSHA v1.1.6
🚀 头条:默认启用 proroot 运行时
传统 proot 基于 ptrace,每个系统调用要两次上下文切换。本版起默认使用 proroot —— LD_PRELOAD + 二进制补丁做进程内路径翻译,零 ptrace 开销。
真机实测启动速度快 5~6 倍,装完即生效,不需要任何设置。
想用回传统 proot:「配置」页取消勾选「proroot 运行时」→ 保存 → 重启 Web。
跑分数据(vivo V2352A / Android 14)
| 场景 | proot | proroot | 提速 |
|---|---|---|---|
| tar 打包(备份走这条) | 608ms | 38ms | +94% |
| stat 密集(node 模块解析) | 635ms | 113ms | +82% |
| 文件读写 | 448ms | 118ms | +74% |
| 目录遍历 | 89ms | 30ms | +66% |
| 容器冷启动 | 45ms | 19ms | +58% |
| 进程创建 | 202ms | 217ms | -7% |
| 关键项合计 | 1594ms | 677ms | +58% |
提速幅度与原理吻合:syscall 越密集省得越多。实际体感(5~6 倍)好于跑分,因为真实启动链要解析几百个模块、每个模块多次 stat + open + read,syscall 密度远高于单项测试。
兜底机制
敢把闭源组件设为默认的前提是它不可用时系统自动绕过它:
- 运行时文件缺失 → 自动降回 proot
- 连续 3 次启动失败 → 强制切回 proot 并在界面告知
- 装机路径(解压、安装六步)始终走 proot
- 自检的「容器运行时」项会显示「所选」与「实际生效」是否一致
最坏情况只是回到原来的速度,不会让环境不可用。proroot 是闭源二进制,详见 THIRD_PARTY_NOTICES.md。
🐛 重要修复
点「重启」十秒后闪退、通知栏一起消失 — 启动前预检里有一条裸 pkill -f node。proot 不隔离 PID,容器内 /proc 看到的是宿主全部进程,那条命令的信号会落到 proot 乃至 App 自己身上。现已改为在 Android 侧按 pid 核对 cmdline 后精确杀。
内置插件一直装不上 — 两个原因叠加:real.substring(4) 少截一个字符,路径变成 roott/dsha-…,dirOk 恒为 false,整段补齐逻辑从未执行;同时仓库里存在两套安置实现,改动一直落在没被调用的那套上。
刚备份的也是「老格式」 — 清单生成在 /root 下,靠打包脚本显式加入参数,而那串拼接在实际执行环境下未生效。现改为直接生成到 .dsh/ 内(该目录必然被打包)。
老版本备份恢复后配置全丢 — .dsh 识别只认 4 个探针,老版本的 config.yaml、以及「只配了 key 还没对话」的备份都识别不出来,然后静默跳过。探针扩到 15 个并加目录名兜底。
会话自愈对最常见的损坏无效 — 非法 JSON 行被静默跳过,既不计数也不触发重写,于是报「无需修复」而坏行仍在。现在区分位置:中间的坏行丢弃重写,末尾的半截行保留(dsh 自己会容忍)。
自检说谎 — 补丁标记查 FIX2 而实际已升到 FIX4,形成「脚本说已打过、自检说没打、怎么修都是 ❌」的死锁;profile bundles 判据看 dependencies 而 dsh 只认 node_modules,导致坏的报成好的。
👀 看得见的自动修复
这个版本的一条主线是让 App 做的事可见:插件补齐、运行时降级、备份清单、会话自愈等自动动作全部记入活动日志。
自检新增五项:容器运行时(区分所选与实际生效)、最近的自动动作、Web 启动状态(此前自检压根不检查 Web 能不能起来)、profile 校准记录、内置插件修复记录。所有 FAIL 都带可执行的下一步。
其他
- 内置 dsh 升级到
0.1.1-rc.2 - 安装流程识别离线包自带的 dsh,不再重复下载
- node-pty 识别自带 prebuild,跳过 headers 下载与现场编译
- 增量更新清单加 RSA-4096 签名,验不过整批拒绝
仅支持 arm64 / Android 8.0+,APK 已内置完整 Linux 环境(约 373 MB)。
sha256 bce4159bacf7f5918e64a05ec8bd097284b121155235b94a041b77e29b463e2b
DSHA v1.1.5
📦 两个包,先看清楚下哪个
| 你的情况 | 下载 | 能否直接覆盖安装 |
|---|---|---|
| 装过开发者直接发的测试包 | deepseekharness-arm64-v1.1.5-legacy-sign.apk |
✅ 可以,数据不丢 |
| 从 Release v1.1.0~v1.1.4 装的 | deepseekharness-arm64-v1.1.5.apk |
❌ 需先备份再卸载重装 |
| 全新安装 | deepseekharness-arm64-v1.1.5.apk |
— |
两个包的功能完全一样,只有签名不同。
legacy-sign 是一次性过渡包,下个版本起只发正式签名版。所以有条件的话建议这次就直接走「备份 → 卸载 → 装正式签名版 → 恢复备份」,一步到位。
legacy-sign 版对你也可能装不上(提示「应用未安装」)。那就只能走下面的卸载重装流程。
⚠️ 关于签名变更(下正式签名版的必读)
为了安全,1.1.5 起改用项目自己的正式签名(此前是 Android debug 签名,密码公开、任何人都能签出「看起来是官方更新」的包)。签名不同的包无法覆盖安装。
正确的升级顺序(务必先备份):
- 打开旧版 DSHA → 设置 → 工作区 → 备份(备份文件落在
Download/DSHA,卸载不会删) - 卸载旧版
- 安装本版 APK
- 首次进入后 → 设置 → 工作区 → 恢复备份(会自动找到刚才的备份)
此后签名永久固定,以后的版本都能直接覆盖升级。
修复(用户能直接感知的)
- 对话历史加载失败 / 每轮结束「本轮运行失败 ENOENT ... session.jsonl.zstd」 —— 两个独立原因叠在一起:内置插件注入的引导消息缺
id,dsh 会拒收整个会话;会话日志用link()发布,在 proot 下发布完即变悬空链接(Android 私有目录禁止真硬链接)。两处都修了 - agent 用 write 工具新建的文件读不出来(报成功但 ENOENT)—— 同一个悬空链接问题的另一处
- 危险命令确认弹窗不出现、命令被判 USER_REJECTED —— 桥只监听了 IPv6 回环,而容器内客户端连的是 IPv4;响应体还缺引号,导致「点了允许也算拒绝」
- 确认弹窗有时看不见 —— 原来前台弹窗与后台通知二选一,App 一切后台就只能干等 60 秒超时。现在两者同时发,从通知点「允许」后弹窗会自动消失
- ADB 无线配对卡在
[2/4],报 PIP_MISSING —— 容器里没有unzip,改用 Python 自带 zipfile,另加一层「直接从 wheel 运行 pip」兜底 - 备份点了没反应、提示「环境可能未安装」 —— 打包命令的文件清单拼接有误,实际是 tar 找不到文件;顺便把失败原因改成弹窗直说,不再让人猜
- 设备操作引导插件不生效(agent 不知道自己能操作手机)—— 插件装了却没真正注册进 profile:
dependencies声明缺失,被 dsh 反复摘除 - 会话目录文件每次启动翻倍、ADB 端口过期后永久连不上、只读命令白名单过宽(
echo >、pm uninstall曾免确认执行)等
新增
- App 层接口(9 个):助手现在不需要 ADB 也能查设备状态、列应用、启动应用、读写剪贴板、发通知、震动、分享、打开链接、把产物导出到
Download/DSHA,还能弹窗问你并等你选择。日常使用已经不必开无线调试 - 一键自检(设置 → 运行自检):13 项只读检查,一次点完就知道桥、插件、会话、备份、补丁、版本标记是否正常,每条失败都写明下一步怎么办,结果可一键复制
- ADB 保活分层加固:连上后 60 秒探一次、断线后 3/6/12/24/45 秒快速重试;网络恢复与屏幕解锁立即重连;深度休眠下靠系统闹钟兜底;端口变化自动重新发现并记住历史端口;配置页新增一键关闭电池优化(不放行的话休眠会冻结连接)
- 备份格式 v2,跨设备可恢复:备份会带上清单和本机插件源码,恢复时自动重建插件、重映射改名过的工作目录、跳过解析不了的插件并在后台静默补装;老备份仍然能恢复
- API key 可以跳过:装好后在 WebUI 的设置里配置官方或第三方 API(自定义接口地址、模型)也行
- 界面:解压/下载/启动/市场四处都有确定式进度、速率与剩余时间;统一了间距圆角字号;修掉「底栏四个 tab 全是蓝色看不出当前页」;配置页拆成三张卡片;引导页加了页码指示
安全
- 正式签名:RSA 4096,有效期至 2056
- 确认请求带序号校验:锁屏残留通知、通知历史里的旧「允许」按钮不会再把授权打到下一条命令上
- 只读命令白名单收紧到子命令级(
pm仅放行 list/path/dump,settings仅 get/list,含 shell 元字符一律需确认) - 发布包不再允许调试器附加
校验
versionCode 45 / versionName 1.1.5
deepseekharness-arm64-v1.1.5.apk (正式签名,推荐)
sha256 38ed150c84a84a01579830349590689ce27f0e7758145de4276e92510fe3ccc2
签名 ed8aaea207f51bf158be5553fb550e8b3cd99a3b8786f4721401a8724e23a693
CN=DSHA, OU=DeepSeek Harness, O=qiannianhuanxiang, C=CN
deepseekharness-arm64-v1.1.5-legacy-sign.apk (老签名,仅供装过测试包的用户覆盖升级)
sha256 2d7b53590d2e85d6426606dce8c957d28f4aca018378c33a582ac2b5006fe5e7
签名 e7e3a31a75946f2669194c972b3dd0c9aea3fc7c50a8b885d2dee710b22a53f5
CN=Android Debug
仅支持 arm64-v8a · Android 8.0+ · 免 ROOT 免 Termux
装好后建议先跑一次「设置 → 运行自检」,有 ❌ 的项按提示处理;遇到问题请把自检结果复制出来一起反馈。
DSHA v1.1.4
DSHA v1.1.4
覆盖安装不丢数据(升级自动备份 + 数据保护)。v1.1.3.1 用户会自动收到更新提示。
🐛 重大修复
- 内置 WebView 白屏转圈(Loading plugins 卡死):系统 WebView 过旧(Chrome<118)自动切 GeckoView 兜底
- 备份恢复失败(GNU tar 长链接名 type K 未处理 → "预构建包损坏")
- 恢复备份误拦含 .. 文件名(v1.2..3.md 等被当路径穿越)
- 会话损坏(SessionPersistenceCorruptionError):看门狗重启等端口关透防双进程写 + 自愈隔离损坏会话 + 工作区清理入口
- workdir 注入(自由输入拼进命令)→ 白名单校验
- 符号链接目标逃逸(恶意备份可指向系统文件)→ 安全校验
- 双重任务通知(旧轮询 + 新插件并存)→ 停用旧轮询
✨ 新功能
- 插件市场链接解析模式:粘贴 GitHub 链接自动解析展示,点安装
- shell 增强改善:agent 只用必需 shell + 报备确认 + root 手动授权(配置页开关)
- 精准任务通知:内置插件监听 turn/end → App 通知(替代轮询)
- 版本比较升级:完整版本(0.1.1-rc.2 正确识别,跨小版本)
🛠 适配
- deepseek-harness 0.1.1-rc.2 全面适配
- 离线包预置 task-notifier 插件
📦 内容
- 内置 Ubuntu 24.04 + Node 24 + dsh(在线自动升级 0.1.1-rc.2)
- 仅 arm64-v8a,Android 8.0+
DSHA v1.1.3.1
DSHA v1.1.3.1(紧急修复版)
修复 v1.1.3 的严重 bug:装完最新 dsh(0.1.1-rc.2)仍显示"未安装" + 重启反复重装。
🐛 修复内容
- 合并步骤检查 R 位污染:dsh 版本号拼进 R/U 位解析 → ⑤ 永远判定未安装 → 反复重装。已改为单独 echo V= + 0/1 位。
- echo V=$C|$E 管道符 bug:
|被 shell 当管道 → 输出异常。已改引号空格分隔。 - 版本判定全面用完整版本比较(0.1.1-rc.2 正确识别为新版)。
对已装用户
- v1.1.3 用户打开 App 会收到"发现新版本 v1.1.3.1"推送(版本号已 bump)
- 更新前自动存档(备份一次)→ 覆盖安装即可
内容
- 内置 Ubuntu 24.04 + Node 24 + dsh(在线自动升级到 0.1.1-rc.2)
- 仅 arm64-v8a,Android 8.0+
DSHA v1.1.3
DSHA v1.1.3
覆盖安装不丢数据(升级自动备份 + 数据保护)。v1.1.2 用户会自动收到更新提示。
🐛 崩溃修复(必现)
- 恢复备份闪退(NPE:Can't toast on a thread without Looper)——后台线程 Toast 切主线程,彻底修复
🔄 deepseek-harness 0.1.1-rc.2 适配
- 版本从 0.1.0-rc.X → 0.1.1-rc.X,全面改完整版本比较(旧逻辑只比 rc 号会把新版误判旧版 → 永不升级)
- 安装 pin / 离线包 DSH_VERSION 更新到 0.1.1-rc.2
- 自动升级检测用完整版本,跨小版本正确判断
✨ 新功能
- 插件市场顶部:GitHub 仓库链接安装(粘贴 URL → 自动解析 → 安装)
- agent 通过 App 层交互:rootfs 挂载 /sdcard(读外部文件)+ 3090 桥新增通知/Toast/读文件端点
- 极简模式设备引导:systemPrompt 注入失败 → 改为 agent/pre-step 用户消息前注入(会话级幂等,新对话只注入一次)
- 插件导入自动注册(之前只解压不生效)
🛠 其他修复
- deepseek-pet 空目录崩溃自愈(不再预创建 /root/.codex/pets)
- 内置插件可禁用(悬空链接语义修复)
- 局域网访问多轮修复(CORS / Origin 重写 / 补丁路径覆盖 rc.8 嵌套布局)
📦 内容
- 内置 Ubuntu 24.04 + Node 24 + dsh 0.1.1-rc.2(离线包重建时更新)
- 仅 arm64-v8a,Android 8.0+
DSHA v1.1.2
DSHA v1.1.2(正式版)
覆盖安装不丢数据(升级自动备份 + 数据保护)
✨ 相比 v1.1.1 的新功能
- 内置插件塞进离线快照:mobile-adapt(移动端 UI 适配)+ device-shell-guide(设备 Shell 引导)预置进离线包,解压即用
- 更新机制智能化:内置插件资产版本化(改 UI 老用户自动更新)、离线包升级感知(发现新版提示重解压)、dsh 主动查新版本自动升级
- 更新前自动存档:检测到新版弹窗前自动备份一次
- 分步安装显示"⭐可更新":装了旧版(rc.6)时显示可更新而非未安装
- 低版本安装适配:老版本升级自动分层迁移(marker/布局/结构)
🐛 重大修复(30+)
- 🔴 危险命令确认 token 鉴权(之前确认弹窗永远失败)
- 🔴 dsh 依赖自愈假成功(npmmirror 元数据不一致导致子包缺失)
- 🔴 插件禁用后"原地消失"/"切页显示启用"/"操作失败"(悬空链接语义)
- 🔴 API key shell 注入转义
- 🔴 终端页卡顿(proot 检查移后台)、转屏丢会话
- 🔴 3090 桥串行卡死、cmd 解析带尾巴、token 并发竞争
- 🟡 局域网访问多轮修复(CORS/Origin 重写/补丁路径覆盖 rc.8 嵌套布局)
- 🟡 恢复备份/重解压前自动停 Web(防数据损坏)
- 🟡 自定义 workdir 升级丢 .env(已修:遍历所有工作目录)
- 🟢 大量注释完善、死代码清理
📦 内容
- 内置 Ubuntu 24.04 + Node 24 + dsh rc.8(离线包)
- 仅 arm64-v8a,Android 8.0+