在安卓 Termux 上打补丁编译并运行 dsh
29.5/100
综合分
0
GitHub 星标
—
npm 周下载
—/5
用户评分
数据截至 2026/10/15 · 周下载取自 npm 全网(含 CI / 镜像),非本站安装数;综合分由星标、活跃度与兼容性检查合成。
安装命令 · 需先装 dsh CLI 引擎
dsh plugin --profile web add mumuxiao722/dsh-termux-build该包不可直接 npm 安装,改从 GitHub 源安装(明细见下方安装检查)
状态速览
判定依据:实装验证 · 静态安装检查 · 自动扫描 · 仓库维护状态信任档位:需留意
图例:✓ 通过! 需注意— 未判定 / 无数据· 「未判定」= 本站尚无数据,不代表插件有问题
档位由哪些信号合成
本站实装验证(真实安装 L4 覆盖全站;L5 为运行时冒烟或实机截图,覆盖范围小于 L4) · 验证所用 dsh 版本 · 静态安装检查 · 风险分级 · 仓库维护状态。 下方各区块是它的证据明细。
给这个插件打分还没有人投票↓
用户评分
还没有人投票,来当第一个
README
由 DeepSeek 最新模型翻译生成dsh-termux
在 Termux(Android)上构建并运行 DeepSeek Harness(dsh)所需的源码补丁和说明。
这是什么
dsh 没有官方 Android 支持,已发布的 npm 产物在 bionic 上跑不起来。本仓库提供:
1. dsh-termux-android.patch —— 运行时源码补丁:涉及 6 个 JavaScript 文件、13 个 hunk。所有人都需要这个。
2. koffi-android.patch —— koffi 的编译期 C++ 补丁(3 个 hunk)。只有你自己编译 koffi 时才需要。
3. 预编译的 .node 二进制文件,放在 Release 里,你可以完全跳过编译。
4. 本文档 —— 完整的手动流程:依赖检查、原生模块、应用补丁、验证。
没有构建脚本。装依赖、编译、怎么编译,全由你决定。
我需要哪个补丁?
| 情况 | dsh-termux-android.patch(JS) | koffi-android.patch(C++) |
| 用 Release 里的预编译 koffi | 必需 | 不需要 —— 已经烘焙进 koffi.node |
| 从源码编译 koffi | 必需 | 必需 |
之所以拆开,是因为 C++ 补丁只在编译期起作用。
展开完整文档(README 剩余 1 节)
dsh-termux
在 Termux(Android)上构建并运行 DeepSeek Harness(dsh)所需的源码补丁和说明。
这是什么
dsh 没有官方 Android 支持,已发布的 npm 产物在 bionic 上跑不起来。本仓库提供:
1. dsh-termux-android.patch —— 运行时源码补丁:涉及 6 个 JavaScript 文件、13 个 hunk。所有人都需要这个。
2. koffi-android.patch —— koffi 的编译期 C++ 补丁(3 个 hunk)。只有你自己编译 koffi 时才需要。
3. 预编译的 .node 二进制文件,放在 Release 里,你可以完全跳过编译。
4. 本文档 —— 完整的手动流程:依赖检查、原生模块、应用补丁、验证。
没有构建脚本。装依赖、编译、怎么编译,全由你决定。
我需要哪个补丁?
| 情况 | dsh-termux-android.patch(JS) | koffi-android.patch(C++) |
| 用 Release 里的预编译 koffi | 必需 | 不需要 —— 已经烘焙进 koffi.node |
| 从源码编译 koffi | 必需 | 必需 |
之所以拆开,是因为 C++ 补丁只在编译期起作用。它已经烘焙进预编译的 koffi.node,所以你用预编译版本就永远不需要它 —— 而且就算应用了也是空操作,因为你并没有重新编译。两个文件都用普通的 patch -p1 应用;见 4. 应用源码补丁。
适用范围
补丁刻意保持最小:只动 Android 上真正会失败的地方,不改任何 dsh 业务逻辑。每处 JS 改动都用运行时的 process.platform === "android" / !== "android" 检查兜住,所以在其他平台上就是死代码。
适用于:dsh 0.2.0-rc.2(package.json 里的 version 字段)。其他版本未经验证。
前置条件
先检查环境;缺什么就装什么,怎么装随你。
必需
| 项目 | 检查 | 缺失时 |
| Node.js ^22.19 \|\| >=24 | node -v | pkg install nodejs-lts |
| npm | npm -v | pkg install npm |
| Android API 级别 | getprop ro.build.version.sdk | 已在 API 24 上验证;更低级别需自行检查 |
| patch | command -v patch | pkg install patch |
| Termux ripgrep | command -v rg | pkg install ripgrep |
| git | command -v git | pkg install git |
只有编译原生模块时才需要
如果你用 Release 里的预编译二进制文件,跳过这一节。
| 项目 | 检查 | 缺失时 |
| 工具链 | command -v clang cmake make python pkg-config | pkg install clang cmake make python pkg-config |
| zlib / openssl 头文件 | ls $PREFIX/include/zlib.h $PREFIX/include/openssl/ssl.h | pkg install zlib openssl |
流程
捷径: 四个原生模块的预编译二进制文件都附在 GitHub Release 上。如果你用的是 ARM64 / API 24,装好 dsh 和它的运行时依赖后,可以直接跳到 4。预编译包不匹配你的环境,或者你想要可复现的构建时,再从源码编译。
1. 安装 dsh
跳过所有安装脚本 —— 原生模块单独构建:
npm i -g @deepseek-ai/dsh@0.2.0-rc.2 --ignore-scripts --no-audit --no-fund
记下安装路径,后面要用:
DSH_ROOT="$(npm root -g)/@deepseek-ai/dsh"
NM="$DSH_ROOT/node_modules"
2. 添加 Android 运行时依赖
npm i -g @img/sharp-wasm32 esbuild @esbuild/android-arm64 --ignore-scripts --no-audit --no-fund
sharp 没有原生 Android 包,会回退到 WASM;esbuild 需要显式指定 android-arm64 平台包。
用 pkg install ripgrep 安装 ripgrep(见上表)。
3. 提供原生模块(必需)
四个模块必须全部就位,缺一不可 —— 少一个 dsh 就起不来。你可以从 Release 下载预编译包,也可以自己编译;Release 说明里给出了每个模块的确切安装路径。
| 模块 | 为什么需要 |
| koffi | dsh 走 FFI;Node 加载不了 glibc 预编译包 |
| node-pty | Bionic 没有 Android 预编译包 |
| node-addon-require-builtin | 上游根本没发布 Android 产物 |
| node-addon-system flock | 单写者会话锁;上游只发布 glibc 版本 |
从源码编译
koffi —— 先打 koffi-android.patch,因为它改的是 base.cc,然后再编译:
cd "$DSH_ROOT"
patch -p1 -N --forward < /path/to/koffi-android.patch
cd "$NM/koffi"
node ./cnoke.cjs -P . -D src/koffi --release
node-pty:
cd "$NM/node-pty"
node-gyp rebuild --nodedir="$PREFIX"
node-addon-require-builtin —— 构建入口在包内的 native-src/。上游没有发布 Android 产物,所以要从源码构建:
cd "$NM/node-addon-require-builtin/native-src"
npm i
NARB_PRODUCT=1 npx node-gyp rebuild --nodedir="$PREFIX"
narb_product 默认是 internal-builtin;你必须传 NARB_PRODUCT=1,才能得到可加载的 binding。
把产物放到加载器期望的位置。它会查找 build/<backend>/<abi>-<platform>/require_builtin.node,其中 <abi> 固定为 napi-v9(Node-API 9):
mkdir -p "$NM/node-addon-require-builtin/build/napi/napi-v9-android-arm64"
cp build/Release/require_builtin.node "$NM/node-addon-require-builtin/build/napi/napi-v9-android-arm64/"
flock —— 上游发布的 node-addon-system-{linux,darwin}- 里没有 android 包。加载器根据 report.header.glibcVersionRuntime 选择 bin/glibc 或 bin/musl;在 bionic 上这个字段是空的,所以产物放进 bin/musl:
cd "$NM/@deepseek-ai/node-addon-system/build-src"
node-gyp rebuild --nodedir="$PREFIX"
mkdir -p "$NM/node-addon-system-android-arm64/bin/musl"
cp build/Release/system.node "$NM/node-addon-system-android-arm64/bin/musl/"
printf '{"name":"@deepseek-ai/node-addon-system-android-arm64","version":"0.1.2-termux","main":"index.js"}\n' \
"$NM/node-addon-system-android-arm64/package.json"
echo 'module.exports = {};' > "$NM/node-addon-system-android-arm64/index.js"
build-src/flock.c 就是这个插件需要的实现。旁边的 src/main.c 是独立的 Landlock 启动器命令行,和 flock 无关;bionic 也没有 Landlock,binding.gyp 不会编译它。
4. 应用源码补丁
cd "$DSH_ROOT"
Always required
patch -p1 -N --forward < /path/to/dsh-termux-android.patch
Only if you compiled koffi yourself (skip if you used the prebuilt koffi.node)
patch -p1 -N --forward < /path/to/koffi-android.patch
重复执行是安全的:-N 会跳过已经应用的补丁块。patch 会为跳过的补丁块留下 .rej 文件,这是正常现象;用下面的命令删掉:
find node_modules -name '.rej' -delete
5. 验证
node -e "require('koffi'); console.log('koffi', require('koffi').version)"
node -e "require('node-pty'); console.log('node-pty OK')"
node -e "require('sharp'); console.log('sharp OK')"
三条命令都没报错,说明原生模块没问题。启动 dsh:
dsh web
Web UI 会打印一个带 token 的 URL。
逐个文件确认补丁是否生效
补丁悄悄应用失败时,症状很隐蔽 —— 工具会默默降级,而不是直接报错。逐个抽查:
cd "$(npm root -g)/@deepseek-ai/dsh"
session single-writer lock
grep -c "platform !== 'android'" node_modules/@deepseek-ai/node-addon-system/lib/flock.js
write tool atomic publication
grep -c COPYFILE_EXCL node_modules/@deepseek-ai/dsh-fs-local/lib/index.js
image read/write
grep -c publishNoReplace node_modules/@deepseek-ai/dsh-attachment-local/lib/index.js
grep / glob
grep -c 'join(executable.dir, "rg")' node_modules/@deepseek-ai/dsh-tool-fs-search/lib/index.js
terminal
grep -rc 'platform === "android"' node_modules/@deepseek-ai/dsh-subprocess-local/lib/runner-launch-.js
每条都应该输出 1 或更大。输出 0 说明那个文件没打上补丁 —— 重新执行 patch -p1 -N --forward。
这个补丁修了什么
没有这个补丁,dsh 在 Termux 上可不只是「有点糙」—— 一整类功能要么直接失败,要么悄悄降级。下表列出你实际会碰到的症状。
| 症状 | 根本原因 | 修复位置 |
| 会话完全无法保存,每一轮都失败并报 ERR_FLOCK_UNSUPPORTED_PLATFORM | dsh 用文件锁保证单写入者;flock 的平台白名单只允许 linux/darwin,而 Termux 上报的是 android | node-addon-system/lib/flock.js + 自行构建的 system.node |
| write 工具失败并报 EACCES | Android 的 SELinux 禁止在应用域创建硬链接,而 dsh 通过 link() 发布原子写入 | dsh-fs-local/lib/index.js |
| read_image / save_image 失败并报 EACCES | 同样的原因,出在附件发布的两处 link() 调用点 | dsh-attachment-local/lib/index.js |
| read_image / save_image 失败并报 open '/data/data': EACCES | ensureDurableHome 为了持久性,会刻意对 $HOME 的每一级祖先目录一路 fsync 到文件系统根。在 Termux 上 $HOME 是 /data/data/com.termux/files/home,这条链会穿过应用数据根目录,而沙箱禁止打开它 | dsh-attachment-local/lib/index.js |
| grep / glob 工具总是失败并报 SEARCH_FAILED | dsh 的搜索不查 PATH;它导入 @vscode/ripgrep 并使用该包里的 rgPath,但这个包没有发布 android-arm64 变体(registry 里只有 linux/darwin/win32) | dsh-tool-fs-search/lib/index.js + pkg install ripgrep |
| Web UI 里的终端打不开,启动日志报 terminal inspection is unsupported on platform android | createProcessInspector 是硬编码的三分支白名单,没有 android 分支,所以加载时就抛错;Android 就是* Linux,而这个 inspector 只读 /proc,并给自己启动的进程发信号,这两件事在 Termux 上都能用,所以把它并进 linux 分支就够了 | dsh-subprocess-local/lib/runner-launch-.js |
| FFI 相关功能编译或加载失败 | 在 Bionic 上 statx 被 __INTRODUCED_IN(30) 藏起来,于是 C++ 把它当成构造函数;posix_spawn 的 file actions 需要 API 28 | koffi/lib/native/base/base.cc(编译期) |
关键词列表,方便你判断遇到的问题是否落在这个范围内:
ERR_FLOCK_UNSUPPORTED_PLATFORM
SEARCH_FAILED / ripgrep launch failed
Could not find @vscode/ripgrep-android-arm64
terminal inspection is unsupported on platform android
EACCES (link / hard link)
EACCES: open '/data/data'
为什么 grep / glob 用 Termux 的 rg,而不是 npm 包
值得单独说明,因为这个问题没法靠「装个东西就行」解决。
dsh 的搜索工具不查 PATH。它们直接导入 @vscode/ripgrep,并使用该包内记录的 rgPath。@vscode/ripgrep 只发布 linux / darwin / win32 的平台包——没有 android-arm64。所以在 Termux 上这不是「难装」,而是 Node 在导入时就抛错:
Could not find @vscode/ripgrep-android-arm64
每次搜索都会变成 SEARCH_FAILED。补丁在 Android 上跳过这个包,直接指向 Termux 自带的 rg(executable.dir 就是 Termux 的 bin 目录)。
Termux 的 rg 是 bionic 构建,运行正常,语法也兼容。别去 npm 上找 Android 版 ripgrep——根本没有。
dsh 依赖链
搞懂这条链,你就能想清楚补丁落在哪里、升级时什么会变。dsh 是 cordis 插件系统:顶层包平铺依赖约 130 个 @deepseek-ai/dsh- 包,运行时全部落在 node_modules/@deepseek-ai/dsh/node_modules/ 下。
8 个被打补丁的文件在这条链里的位置:
@deepseek-ai/dsh (top level, ~130 flat deps)
├── @deepseek-ai/dsh-app-boot ──────────► node-addon-require-builtin ─┐
│ └── node-addon-native-custom-loader
│ └── build/napi/napi-v9-android-arm64/ ← self-built
├── @deepseek-ai/cordis-plugin-loader ───► node-addon-require-builtin
│
├── @deepseek-ai/dsh-web-app
│ └── @deepseek-ai/dsh-tool-fs-search ◄── patch: point at Termux's rg
│
└── @deepseek-ai/dsh-base
├── @deepseek-ai/dsh-session-persistence-jsonl ◄── patch: rename instead of link
│ └── @deepseek-ai/node-addon-system ◄── patch: allow android
│ └── @deepseek-ai/node-addon-system-android-arm64/bin/musl/system.node ← self-built
├── @deepseek-ai/dsh-fs-local ◄── patch: link → copyFile(EXCL)
│ └── @deepseek-ai/dsh-fs-sandbox
├── @deepseek-ai/dsh-attachment-local ◄── patch: link → copyFile(EXCL) + durability walk
├── @deepseek-ai/dsh-subprocess-local ◄── patch: android → LinuxProcessInspector
└── @deepseek-ai/dsh-sandbox-local ──► node-addon-system
有三点值得知道:
- dsh-base 是枢纽——会话持久化、文件系统、附件、子进程的补丁全挂在它下面。它一坏,一大片功能同时挂掉,而不是一次坏一个工具。
- 两个原生模块用的加载器不同,规则也不同。 node-addon-system 根据 glibcVersionRuntime 在 bin/glibc 和 bin/musl 之间选;node-addon-require-builtin 则去 build/<backend>/<abi>-<platform>/ 下面找。产物放错地方,表现就是「文件明明在那儿,就是加载不了」。
- Termux 永远走不到 glibc 分支——bionic 上 glibcVersionRuntime 是空的,所以 flock 产物必须放进 bin/musl。
补丁改了什么
koffi-android.patch(编译期,3 个 hunk,1 个文件)
只有你自己编译 koffi 时才需要;预编译的 koffi.node 里已经带了这些。
- statx 回退——Bionic 把 statx 声明藏在 __INTRODUCED_IN(30) 后面,所以 API 30 以下 C++ 会把 statx(...) 当成 struct statx 构造。排除 __ANDROID__ 就能让它走通用的 fstatat/fstat 分支。
- 在 API 28 以下禁用 posix_spawn 文件操作 —— 这个辅助函数需要 API 28。dsh 的 FFI 路径从不调用它,所以返回 ENOSYS。
- 把 return true 移到 #endif 外面 —— 这样成功路径在所有平台都能返回。
dsh-termux-android.patch(运行时,13 个 hunk,6 个文件)
@deepseek-ai/dsh-subprocess-local(2 个 hunk)
createProcessInspector 只接受 linux / darwin / win32,其他平台一律抛错:
subprocess-local: terminal inspection is unsupported on platform android
Termux 报告 process.platform === "android",于是插件加载失败,本地终端功能完全不可用。
Android 就是 Linux。那个检查器只读 /proc/<pid>/stat、列 /proc、调用 ps/kill,而且只检查自己启动的子进程 —— 它从不跨越应用边界,因此从不触碰 SELinux。把 android 并入 linux 分支就够了。
这个文件名里带内容哈希(runner-launch-<hash>.js),dsh 升级时会变。
@deepseek-ai/node-addon-system lib/flock.js(1 个 hunk)
平台允许列表只放行 linux/darwin,于是 Termux 抛出 ERR_FLOCK_UNSUPPORTED_PLATFORM,整个会话写入都会失败。flock() 本身在 bionic 上能正常工作,只需要放宽这个检查。
@deepseek-ai/dsh-session-persistence-jsonl lib/index.js(2 个 hunk)
Android 沙箱用 EACCES 拒绝 link(2),于是发布初始 JSONL 会话失败。在 Android 上改用 rename()。
@deepseek-ai/dsh-fs-local lib/index.js(2 个 hunk)
Android 的 SELinux 禁止在应用域创建硬链接,所以 link() 总是以 EACCES 失败。writeFileAtomic 的 createIfAbsent 分支回退到 copyFile(COPYFILE_EXCL),它用 O_CREAT|O_EXCL 创建目标文件 —— 语义上等价。
@deepseek-ai/dsh-attachment-local lib/index.js(5 个 hunk)
两处基于 link() 的发布(publishImmutableAlias、publishStagedObject)同样回退到 copyFile。另外修复 ensureDurableHome 的持久化遍历:它会刻意对 $HOME 的每一级祖先目录 fsync,一直上溯到文件系统根目录,而在 Termux 上 $HOME=/data/data/com.termux/files/home,这条链会经过 /data/data —— Android 沙箱禁止应用打开它,导致每次 saveImage/read_image 都失败。打不开的层级本来就在本应用的同步范围之外,所以直接停止遍历,而不是让整个保存失败。
@deepseek-ai/dsh-tool-fs-search lib/index.js(1 个 hunk)
dsh 的 grep/glob 不查 PATH,它用的是 @vscode/ripgrep 的 rgPath,而那个包没有 @vscode/ripgrep-android-arm64(registry 里只有 linux/darwin/win32)。导入时抛 Could not find,让每次搜索都变成 SEARCH_FAILED。在 Android 上把它指向 Termux 的 rg。
已知限制
插件:Android 上的 pnpm 与硬链接(不在本补丁范围内)
dsh 用 pnpm 管理配置档插件。Android 沙箱禁止创建硬链接,而 pnpm 默认依赖硬链接来复用 store 里的包——所以插件安装要么失败,要么留下一个损坏的 node_modules。
这既不是 dsh 的 bug,也不是这个补丁能修的问题:补丁只覆盖 dsh 自己的包,插件不在范围内。你需要在配置档的 pnpm-workspace.yaml 里加两项设置:
nodeLinker: hoisted
packageImportMethod: copy
- packageImportMethod: copy —— 用复制代替硬链接。这一项是必须的。
- nodeLinker: hoisted —— 把依赖树摊平成 dsh 期望的扁平 node_modules 结构
还有两件事值得知道:
- 安装带 install/prepare 脚本的插件时,加上 --ignore-scripts。有些插件依赖 Linux 原生二进制(比如 cloudflared),在 Android 上根本编译不出来,而 pnpm 12 会把「ignored build scripts」当成硬错误,直接中止整个安装。
- 从 GitHub 安装比从 npm 安装更容易失败,因为它需要 git ls-remote。只要 npm registry 上有版本,就优先用 npm 上的版本,彻底绕开 git。
注意: Termux 网络经常连不上 GitHub —— git ls-remote 和原始下载会超时,或者报 SSL_ERROR_SYSCALL。从 Termux 访问 npm registry 可靠得多。所以只要包在 npm 上有,就按版本安装(npm i <pkg>@<version>),别用 GitHub spec。Release tarball 同理:如果 github.com 对你来说很慢,里面的二进制可以从 npm 源码加上补丁复现出来。
其他
- 没有沙箱后端 —— Termux 既没有 Landlock 也没有 bubblewrap,容器隔离用不了。在 Web UI 里把命令执行设为 Manual Approval 或 Full Access。
- link() 降级 —— Android 上没有硬链接,所以所有原子发布都走 copyFile。功能上等价,但失去了共享 inode 的特性。
- flock 二进制 —— 必须手工编译,或者从 Release 下载。
- 版本绑定 —— 补丁针对 dsh 0.2.0-rc.2。dsh 还是开发者预览版,升级后大概率需要重新生成补丁:拿新版本的干净 npm 副本,重新跑一遍 diff -u。
- subprocess-local 文件名哈希 —— 哈希会随 dsh 升级变化,补丁文件里的路径必须同步更新。
卸载
npm rm -g @deepseek-ai/dsh
补丁只修改安装目录内的文件,不往别处写任何东西;你创建的 node_modules/*-android-arm64/ 目录会随卸载一并删除。
许可证
MIT —— 见 LICENSE。补丁修改了第三方作品,其版权声明保留在打过补丁的文件中:DeepSeek Harness(© 2026 DeepSeek)和 koffi(© 2026 Niels Martignène)。预览分享卡片长什么样 ↓
分享 · DeepSeek Harness Hub
mumuxiao722/dsh-termux-build
在安卓 Termux 上打补丁编译并运行 dsh
相关插件 · 其他
模型破甲清洗HunYiSage/dsh-purge
⚔️ DeepSeek Harness 网络安全红队工具dsh-purge
★ 16,993已汉化DeepSeek 客户端
73
女娲蒸馏alchaincyf/nuwa-skill
输入名人名字,提炼其思维模型与决策方式供你调用
★ 37,308已汉化DSH
72
逆向分析桥接Fanqi89/dsh-rea
REA(Reverse Engineer Anything)MCP 桥接,用来把 REA 逆向工具接入 DSH 插件
★ 51已汉化DSH
72
语音女友beiyege-01/dsh-voice-ai-girlfriend
语音 AI 女友Voice AI girlfriend for DeepSeek Harness:Whisper…
★ 888已汉化DSH
71.6
红队越狱测试套件Minglink/dsh-infinite-gen-5
DeepSeek v4.1 flash 逆向工具无限五代 求 Star 收藏 ⭐欢迎大家提交项目的改进
★ 3,759已汉化DSH
71.4
协同办公空间dream-num/univer-workspace
一个让人类与 AI Agent 共同创作、协作和审阅的开源 Office 工作空间。
★ 2,270已汉化DSH
70.8
这个插件是你维护的吗?
作者本人可认领并核对本条目;认领通过后,详情页会显示「作者已认领」标记。