🎁 福利专区全网大模型免费应用 + 新用户福利 + 注册活动入口,低成本玩转 AI

Termux 安卓构建补丁 mumuxiao722/dsh-termux-build

DeepSeek Harness
mumuxiao72225 天前有提交已提供中文文档扫描:无法判定

在安卓 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 源安装(明细见下方安装检查)

状态速览

判定依据:实装验证 · 静态安装检查 · 自动扫描 · 仓库维护状态
信任档位:需留意
是什么[目录]—
dsh 原生插件 · other
暂无时间戳·判据 →
装得上吗[实装验证]!
实装验证未通过(unknown),装前请到仓库确认最近更新与 issue
L4 · 真实安装等级说明 →
数据截至 2026/10/16·判据 →
安全吗[自动扫描]—
本站尚未对该插件做风险分级
暂未覆盖,不等同于无风险
数据截至 2026/11/04·判据 →
还在维护吗[仓库]✓
活跃:最近一次提交在 25 天前
暂无时间戳·判据 →
图例:✓ 通过! 需注意— 未判定 / 无数据· 「未判定」= 本站尚无数据,不代表插件有问题
档位由哪些信号合成

本站实装验证(真实安装 L4 覆盖全站;L5 为运行时冒烟或实机截图,覆盖范围小于 L4) · 验证所用 dsh 版本 · 静态安装检查 · 风险分级 · 仓库维护状态。 下方各区块是它的证据明细。

验证判据与等级说明 →

可信度证据

⚠︎ 实装验证未通过(unknown · 2026/10/16) ——可能是验证环境差异,装前建议到 GitHub 仓库确认最近更新与 issue。
安全扫描自动 · 静态分析源码
v2.7.0
⚪ 扫描:无法判定尚无人工评估
展开查看扫描说明与证据 ↓

已尝试扫描但取不到可分析的源码:仓库或包不存在、已删除,或为非 JS/TS 实现、未随包发布源码。无法判定,不代表安全。

  • · 包内无可扫 JS
  • · TS 源码(可能为非 JS 实现或未发布源码),无法判定
扫描于 2026/11/4(1 天前) · 范围 全包扫描(包内未声明入口) · 来源 GitHub 仓库

静态扫描只反映源码中出现的调用,不构成安全背书;人工评估与自动扫描相互独立、互不覆盖。

社区实装还没有人打卡 · 装过的第一个就是你
给这个插件打分还没有人投票↓
用户评分
还没有人投票,来当第一个

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)。
预览分享卡片长什么样 ↓mumuxiao722/dsh-termux-build
分享 · DeepSeek Harness Hub
mumuxiao722/dsh-termux-build

在安卓 Termux 上打补丁编译并运行 dsh

这个插件是你维护的吗?
作者本人可认领并核对本条目;认领通过后,详情页会显示「作者已认领」标记。
认领条目 →
回到顶部