Repository navigation
Releases: itiswdwa/dsh-android
Release list
v1.2.1
dsh-android 1.2.1
这一版是应用版本升级,主题是恢复模式 —— harness 起不来的时候,应用不再只能给你一个空白页。
1.2.0 的设备需要安装新的 APK。 恢复模式有一半在应用侧(面板、桥接口、自动进入),
热更新包送不过去;热包也不跨应用版本线,所以这一版的内容只随 APK 下发。
Added
- 恢复模式:harness 起不来时也能进沙箱。连续几次启动失败后应用会自己切换过去 ——
不加载 harness,直接起来一个 SSH 服务和一个 shell。同一 Wi-Fi 用ssh -p 8022 root@<手机 IP>,
插着数据线用adb forward tcp:8022 tcp:8022,只有手机时就点面板里的「手机内控制台」
(一个不依赖 harness 的行模式终端)。密码是每次进入时新生成、退出即失效的令牌 - 恢复模式支持端口转发:在沙箱里把 harness 重新拉起来之后,
用ssh -p 8022 -L 3080:127.0.0.1:3080就能从电脑的浏览器打开它 —— 手机自己渲染不出来时这条最省事 - 面板里可以直接复制连接命令、换一个新令牌、退出恢复模式;SSH 主机密钥由每台设备自己生成
(存在/root/.dsh-recovery/),不再用载荷里那份所有安装都一样的
Changed
- 沙箱终端服务的会话现在会回收:关掉的标签页、重载的页面以前会在沙箱里各留一个 shell,
攒够 8 个之后新终端就再也开不出来 - 桥接口新增
/recovery/*,/snapshot带上恢复模式状态(给以后在设置页里做一张卡片留的)
Fixed
- 退出恢复模式后 root 密码一定回到锁定:原来只靠脚本的信号处理和「进程退出后补一次」,
而应用停沙箱是直接杀进程、紧接着 800 毫秒就启动下一个 guest,两处都可能被跳过;
现在正常启动时也会锁一次,不依赖信号也不依赖时序 - 一行畸形请求不再能让终端服务整个退出(恢复模式下它是唯一的入口)
- 更新不会因为版本号倒退而卡住:
versionCode以前只靠公式(1.2.1→ 10201)或环境变量,
而这条线已经原地重发到 10212 —— 现在它记在仓库的VERSION_CODE里,重建也还是 10213
运行时(t3)
- 载荷里的 harness 升到
0.2.0-rc.2(npm 上的latest;上游没有不带后缀的0.2.0)。
这是t的变化,所以必须装新 APK,热包送不过去。1.2.1 的 APK 同时是"恢复模式"和"t3 运行时"。 - 升之前在这台设备上逐项验证过:硬链接补丁的四个发布点(三处 import 行、四个调用点、注入锚点)
在0.2.0-rc.2里原样还在,所以补丁不会触发"上游改了"的拒绝;装完在 Node 22.23.2 上跑
市场冒烟,对照组(不加载市场)与实验组(加载市场)各一次真实调用都正常;
用真实 profile 分别起 0.1.7-rc.2 与 0.2.0-rc.2,两边页面都是 200 且 35334 字节逐字节相同 - 补上了
prepare_rootfs.sh缺的一步:guest 工具(git/curl/python3/tmux/openssh-server 等)
以前是手工装进 rootfs 的,仓库脚本里没有 —— 也就是说照仓库脚本从头构建出来的载荷没有 sshd,
而恢复模式正需要它。现在这一步在脚本里,并且装完硬校验(缺任何一个就构建失败,
不会让一个"起不来恢复模式"的载荷发出去)
注意
- 恢复模式期间 harness 不在运行:手机上看不到会话列表、也不能对话,它是在「修」而不是「用」
- 修好之后记得点「退出恢复模式」,否则下次启动还是恢复模式
- 不想装 APK 的话,已装的设备也可以在恢复模式里用
scripts/upgrade-dsh.sh把 harness 单独升到
0.2.0-rc.2(见docs/UPGRADE-DSH.md);但换t之后载荷与设备不再一致,
下次装全量包会把它覆盖回去
安装:下载本页的 dsh-android.apk,覆盖安装即可;会话、API Key、挂载与设置都会保留。
首次启动需要解包内置运行时(约 2 分钟),之后冷启动约 5 秒。完整说明见 README。
v1.2.0
dsh-android 1.2.0
这一版是应用版本升级,三块改动一起进来:终端重写(亮色白底、弃用 xterm、标签页)、
悬浮球改造(单窗口、状态外部驱动、一堆崩溃与裁切修复)、issue 修复与预装
(#1/#2/#3/#4,含沙箱预装 pnpm 与插件市场)。
1.1.5 的设备需要安装新的 APK。 热更新包不跨应用版本线(应用端按
<app>-t<terminal>-前缀
判断,1.1.5 的机器不会收到 1.2.0 的热包),设置页里会显示"有新外壳"而不是热更新。
Changed
- 终端重做:亮色主题下终端是白底(暗色保持原样);弃用 xterm,改成自写的终端渲染 ——
中文输入法、长按选择复制、方向键/回车/回删、光标位置都按手机的用法重做;底部新增功能键行
(Esc / Tab / Ctrl / 方向 / 粘贴 / 复制),按下有轻触反馈 - 终端支持标签页:一个面板里多个会话用 tab 切换(可新建、关闭,最多 4 个);侧边栏「终端」
重复点只激活已有终端,不再每点一次就新开一个 shell;关掉标签或插件卸载会把 pty 交还 - 悬浮球改成单窗口:球、输入条、状态气泡现在是同一个窗口(收起=球矩形、展开=条、状态=按文字
自适应的气泡),形变过程中不再被上层窗口盖住 —— 这是"两条胶囊、动效看不见"的根治 - 球上的状态改为外部驱动:新增
ball_doing(每次工具调用必带),由独立的状态总结器插件按会话
事件推到球上,不额外调用模型;干活的模型不再被要求自报状态。停留规则:下一条是"思考中"
最多等 2 秒,是工具调用最少停 0.5 秒
Added
- 沙箱预装
pnpm(自包含单文件,随运行时包下发):插件安装 /dsh plugin这类操作用得上(issue #4)
Fixed
- 方向键的光标不再"看不见落在哪":以前底部整行输入框会把 ←/→ 吃掉(一个字节都不发给 shell),
而 xterm 自己的光标又是另一套逻辑;现在只有一条输入路径,屏幕上的光标就是 shell 的光标 - 键盘收起后能稳定唤回:点一下终端屏幕即可输入;连续尝试失败会给出提示,而不是静默失效
- 全新安装不再缺「安卓沙箱」设置页与终端按钮(issue #3):播种闸门从"目录是否存在"改成
"profiles/web/package.json是否存在"(热包会先把插件目录建出来,目录判断必然被跳过) - 已经装坏的设备会被自动补齐:启动时按文件补齐 profile(缺哪行补哪行,从不覆盖用户自己的
bundle 列表),并把丢失的插件注册行加回去 —— 以前入口都在没注册的插件里,用户无法自救 - 现有设备自动获得三个内置插件:状态总结器、浏览器预览、插件市场(随热包下发,profile 行自动补)
- issue #2:装瘦包 / 从没检查过更新的机器上,「下载运行时」按钮点着没反应、文案也看不懂 ——
按钮原来只认更新清单里的地址,而"装了瘦包、从没检查过更新"恰好是空的。现在它回退到 release 资产
(releases/latest/download/payload.zip与payload.manifest),文案改成一屏可照做的中文引导:
为什么需要运行时、大约多大、直接下到 App 私有目录(不用自己找位置、解压、手动导入)、下完自动导入、
看到"已安装"后终端就能用,失败会写明原因并可重试(只改插件引导层,未动 App Java) - 侧边栏 ⋯ 菜单:点会话右侧「三个点」时菜单闪现后消失、还直接进了那个会话 —— 根因是我们
自己的手机布局补丁在 capture 阶段就把抽屉收了起来(菜单的锚点被抽走)。已修并重新注入 - 球的加载指示真的在转:换成会转的圆环(鲸鱼居中),"思考中"也转圈;固定文案不再每 1.4 秒换词
- 对勾徽标不再被裁:
done收回成球时✓收进圆内,不再被圆的边切掉半个 - 气泡按行数长高(40 / 52 / 72dp):两行字不再被硬塞进球的 40dp 里
- 不再"莫名其妙重启":
morph()动画完成回调为空时的空指针已兜底,并把所有调用点补齐 - 球会话不再逼你去 DSH 点选项:球专用会话结构性移除提问卡片、免审批,配
floating-ball
skill(一句话结论 + 纯文本编号澄清);收件箱自愈 —— 球会话被删掉后,下一句会自动开新线程,
不再永久哑掉
注意
- 瘦包(slim)用户:
pnpm随运行时包(payload)一起发,装完瘦包不会自动重新下载 payload。
要拿到pnpm(以及本次 payload 内的改动),需要重新下载一次运行时(设置 → 检查更新,约 230 MB);
在那之前热包只会带来插件、技能与沙箱脚本的改动。装了完整包的不受影响 - 底部功能键行的轻触反馈、「应用过的热包在重启后不被 APK 内建内容覆盖」、以及侧边栏 ⋯ 菜单
这三条修复都要等新 APK 装上才生效(它们分别落在 App 的 Java 与前端 assets 里);只装热包不生效
安装:下载本页的 dsh-android.apk,覆盖安装即可;会话、API Key、挂载与设置都会保留。
首次启动需要解包内置运行时(约 2 分钟),之后冷启动约 5 秒。完整说明见 README。
v1.1.5
dsh-android 1.1.5
这一版把此前三个热包(1.1.4-sp1/sp2/sp3)的内容一并收了进来,另外换了新的版本编号方式。
Added
- 手机助手:可以直接让助手操作这台手机。应用内新增无障碍服务(读屏、点击、输入、滑动),
以及一个常驻的悬浮球:点一下说话、长按打字,说完把话交给会话,助手用屏幕上的文字
(而不是猜坐标)去点按钮、在别的应用里输入。设置页新增「手机助手」,三项授权逐个有状态与入口 - 沙箱里新增
ui命令,给助手用:ui tree看当前屏幕、ui click "发送"按文字点、
ui type输入、ui key back、ui swipe、ui open 微信。走无障碍,不需要 Shizuku - 终端版本:沙箱运行时(rootfs、node、dsh、装进去的工具)现在有自己的版本号,与界面版本无关
Changed
- 版本号改成三段:
1.1.5-t2-sp0—— 应用版本 · 终端版本 · 热包序号。
t2是这套运行时,它只在运行时本身变化时才动;sp0表示这一版还没有热更新 - 常驻通知:换成产品图标,正文写出状态与端口,并在通知栏直接提供「停止 / 启动」
- 沙箱里自带
git、curl、python3、ssh、tmux等常用工具,装上就能用
Fixed
- 沙箱里的
apt可以用了:Android 不允许应用创建硬链接,而 dpkg 每写一次数据库都要先用
link()备份status,于是apt install必然失败。现在 guest 全局加载一个兼容层
(/opt/dsh/android/liblinkfix.so):link()被拒时退回复制文件、chown()按沙箱内即 root 的
约定回报成功、stat()为复制出来的第二个名字补上链接数(groupadd靠它判断锁) - 无障碍服务的屏幕描述有界(节点数与深度都有上限),不会把整棵树塞给模型
安装:下载本页的 dsh-android.apk,覆盖安装即可;会话、API Key、挂载与设置都会保留。
首次启动需要解包内置运行时(约 2 分钟),之后冷启动约 5 秒。完整说明见 README。
t2
v1.1.4
dsh-android 1.1.4
Fixed
- 插件更新后界面仍是旧版:应用改为直接写入 harness 读取插件的目录,不再经过沙箱内的复制步骤;
那一步之前任何环节没发生,harness 就会继续加载旧插件(8efe1fd)
Added
- 设置页顶部常显版本号(
应用 1.1.4 · 热包 1.1.4-sp1 · 内置):设备上跑的到底是哪一版,
以前只能靠猜是"功能没写"还是"装了旧版"
安装:下载本页的 dsh-android.apk,覆盖安装即可;会话、API Key、挂载与设置都会保留。
首次启动需要解包内置运行时(约 2 分钟),之后冷启动约 5 秒。完整说明见 README。
1.1.4-sp1 - 2026-09-30
Changed
- 「安卓沙箱」设置页改按 harness 原生设计重绘:按钮、开关、状态点、标签、卡片全部改用 harness
自带的组件库与主题令牌,与旁边的「通用设置」同一套观感,浅色/深色自动跟随(4ae032c) - 发行版卡片用标签标出「当前使用」与「内置」,不再只靠标签页上一个小圆点判断
Fixed
- 英文界面下设置页夹带中文:挂载的「启用/停用」与日志的空状态改用语言表
[1.1.4-sp2] - 2026-09-30
包含 1.1.4-sp1 的全部改动。(20ac8f9)
Changed
- 热更新包的版本号改用
<应用版本>-sp<序号>(1.1.4-sp1、1.1.4-sp2……),
此前显示的那串 16 位内容哈希不再对外展示 - 设置页顶部的版本号改为完整显示:原先把
1.1.4-sp1截断成1.1.4-sp
[1.1.4-sp3] - 2026-09-30
沙箱里的 apt/dpkg 现在能正常工作;代价是硬链接的"两个名字共享内容"变成了复制,包管理器不依赖那一层。
Fixed
- 沙箱里
apt install/dpkg --configure -a必定失败(error creating new backup file '/var/lib/dpkg/status-old': Permission denied):Android 不允许应用进程创建硬链接,而 dpkg
每写一次数据库都要先用link()备份status。现在 guest 全局加载一个小兼容层
(/opt/dsh/android/liblinkfix.so):link()被内核拒绝时退回复制文件,git、curl、
python3、openssh-server、sudo等都能正常安装 adduser/groupadd报lock file already used (nlink: 1):这些工具用link()建锁,
再检查链接数判断锁是否被占;复制不会让链接数增加,兼容层据此如实回报- 安装软件包时 dpkg 把文件属主改成 root 不再以 EPERM 失败(沙箱内本来就是"root"的约定)
应用:设置 → 安卓沙箱 → 检查更新 → 应用热更新。
也可以把 dsh-hot.zip 放进手机的 Download 目录,重开应用即可。
v1.1.3
dsh-android 1.1.3
Fixed
- 修复升级后卡在启动画面:清理旧运行环境的工作原先在主线程上做,而且每次启动都会重来一轮,
而旧树里有一万多个删不掉的残留文件;现在移到后台、只尝试一次,删不干净的目录改名挪开(bbc780e) - 修复挂载不生效:源目录读不到时(
Android/data、SD 卡、没授予存储权限)会被静默丢弃,
沙箱里只看到一个空目录;现在设置页直接写明原因(a2ef690)
Added
- 每条挂载的「测一下」:让沙箱真去列一次目标目录,绑上没有、里面有什么,一眼就有答案(
a2ef690) - 挂载卡片内的「重启服务以生效」:挂载是启动参数,改了必须重启(
a2ef690)
安装:下载本页的 dsh-android.apk,覆盖安装即可;会话、API Key、挂载与设置都会保留。
首次启动需要解包内置运行时(约 2 分钟),之后冷启动约 5 秒。完整说明见 README。