DSH-plugin-android-apk
Manifest valid★ 3Build APKs with DSH (Use dsh to help you build an APK)
dsh-plugin-android-apk
DeepSeek Harness (DSH) 插件:把一个安卓项目文件夹直接构建成 APK。 缺少的工具链(JDK / Android SDK / Gradle)会自动下载到工作文件夹内,不污染用户目录。
更新记录见 CHANGELOG.md。
功能
- 识别 Gradle 安卓工程(
settings.gradle/settings.gradle.kts/build.gradle),可选支持 Gradle Wrapper。 - 自动准备工具链:
- JDK:系统
JAVA_HOME/PATH里有满足要求的 Java(AGP 8 / Gradle 8 需要 ≥17,否则 ≥11,插件会先探测工程里的 AGP 版本)就直接用;否则按当前系统与架构下载对应的 Temurin JDK(Windows/Linux/macOS × x64/aarch64…,Windows 取.zip、其它取.tar.gz)到下载文件夹,并复用上次下载的 JDK,不重复下载。若请求的版本在该平台没有官方构建(例如 Temurin 没有 windows/aarch64 的 JDK 17),会自动沿 LTS 阶梯回退到有构建的版本(17 → 21 → 25)并在日志里说明原因。 - Android SDK:依次检查
local.properties的sdk.dir、ANDROID_HOME、ANDROID_SDK_ROOT、%LOCALAPPDATA%\Android\Sdk;都没有则下载 commandline-tools + platform-tools + build-tools + platform 到下载文件夹,并自动写入local.properties和接受许可。local.properties里失效的sdk.dir(指向已删除的 SDK)会被自动修正。 - Gradle:工程带可用 Wrapper 就用 Wrapper(若 Wrapper 的 Gradle 版本无法在当前 JDK 上运行,例如 Gradle 7.0 配 Java 17,则自动改为下载发行版);否则按
gradle-wrapper.properties里的版本(或配置的gradleVersion)下载发行版。
- JDK:系统
- 运行
assemble<Variant>(默认debug,可用release),把产物 APK 复制到输出文件夹。 - 非 ASCII 路径自动处理:当工程或 SDK 目录路径含有非 ASCII 字符(例如中文路径,AAPT2 在 Windows 上会因此无法读取
android.jar)时,自动把工程和 SDK 复制到一个可用的 ASCII 临时目录(%TEMP%\dsh-android-build)里构建,再把 APK 复制回你的输出文件夹。staged SDK 会缓存复用,不重复下载。 - 所有下载、Gradle 发行版、依赖缓存(
GRADLE_USER_HOME)都放在插件自己的toolchain/目录(<插件安装目录>/toolchain,可用downloadDir覆盖)。放在插件根目录意味着所有会话、所有工程共用同一套工具链——不会每个工作区各留一份几百 MB 的缓存,也不污染用户目录。
安装
在 DSH 宿主机器上(需要 pnpm 在 PATH 上)。把 <插件路径> 换成这个 tarball 在你机器上的实际位置,
<profile> 换成你要装的 profile 名:
dsh plugin --profile <profile> add "<插件路径>/dsh-plugin-android-apk-0.2.4.tgz"
<profile>填什么? 桌面端常见的是desktop,Web 端常见的是web,但名字由你自己决定, 取决于当前跑的是哪个 profile——填错不会报错,只是"装到另一个 profile 去了",当前会话看不到这个工具。 查看本机有哪些 profile:ls ~/.dsh/profiles(Windows:dir %USERPROFILE%\.dsh\profiles)。 想知道当前会话用的是哪个,可在任务管理器里看 DSH 主进程的命令行,末尾那个路径就是...\.dsh\profiles\<名字>。插件与 profile 无关:
cordis.patch.yml按包名插入一行插件,代码里没有写死任何 profile 名, 所以desktop/web/ 自定义 profile 都同样可用。唯一的差别是每个 profile 要各装一次—— 它属于 profile 级依赖;如果你同时用桌面端和 Web 端(通常就是两个 profile),两边都装才会都出现。
说明:
dsh plugin实际是在 profile 目录里执行pnpm add <spec>,然后把声明了dsh.bundle.patch的包加入dsh.profile.bundles层。手动操作等价于: 在~/.dsh/profiles/<profile>执行pnpm add <spec>,再把包名加进package.json的dsh.profile.bundles。
⚠️ 依赖声明为
peerDependencies(0.2.1 起):@deepseek-ai/cordis/@deepseek-ai/dsh-tools/@deepseek-ai/schemastery由 DSH 宿主提供并做解析拦截, 插件不能自己装一份——否则 profile 里的旧副本会遮蔽宿主自己的tools行,导致1 required plugin did not activate、桌面端无法启动。请不要在 profile 里手动pnpm add这三个包。
使用
装好后,直接对 Agent 说“把 xxx 文件夹构建成 APK”,或显式调用工具:
build_android_apk(project="myapp", variant="debug", clean=false)
参数:
| 参数 | 说明 | 默认 |
|---|---|---|
project | 安卓工程文件夹路径(相对路径基于会话工作目录) | 必填 |
variant | Gradle 变体(debug / release 等,大小写保留:stagingDebug → assembleStagingDebug) | debug |
clean | 是否先 clean 全量重建 | false |
downloadDir | 工具链下载目录(相对路径基于会话工作目录) | <插件目录>/toolchain |
apkOutputDir | APK 复制目录 | <workspace>/apk |
gradleVersion | 无可用 Wrapper 时下载的 Gradle 版本 | 8.9 |
compileSdk | 覆盖自动检测的 compileSdk | 自动检测,未知时 34 |
返回:ok、message、apks[](原始路径 + 复制路径 + 大小 + staged 标记)、logTail、durationMs 等。只返回本次构建产出的 APK(按修改时间过滤,不会把上次的旧包一起报上来)。
插件级配置(cordis.patch.yml 里的 config,可选):
config:
defaultVariant: debug
jdkMajor: 17
gradleVersion: "8.9"
下载与镜像
| 组件 | 默认源 | 回退镜像 |
|---|---|---|
| JDK (Temurin) | api.adoptium.net | mirrors.tuna.tsinghua.edu.cn/Adoptium |
| Gradle | services.gradle.org | mirrors.cloud.tencent.com/gradle、mirrors.aliyun.com |
| Android cmdline-tools | dl.google.com | mirrors.cloud.tencent.com/AndroidSDK |
网络受限(如国内直连 Google 不稳)时,插件会自动尝试回退镜像;也可以先用代理保证
dl.google.com / services.gradle.org / api.adoptium.net 可达。
下载完整性校验:拿得到上游官方摘要时会逐个比对,不匹配的镜像直接跳过并换下一个——
| 组件 | 校验来源 | 算法 |
|---|---|---|
| JDK (Temurin) | Adoptium assets API 的 checksum(清华镜像为 <归档>.sha256.txt) | SHA-256 |
| Gradle | <发行版>.sha256(与 zip 同目录) | SHA-256 |
| Android cmdline-tools | Google repository2-*.xml 里的 <checksum> | SHA-1 / SHA-256 |
摘要源拿不到(镜像未提供、dl.google.com 不可达)时跳过校验、照常下载,不会阻塞构建;
校验通过会在 logTail 里打印 [dl] … checksum verified …。
目录结构
安装包(tarball)内包含:
package/
├── package.json # dsh.bundle.patch 声明(profile 层识别依据)
├── cordis.patch.yml # 插件行:android-apk-builder
├── lib/
│ ├── index.js # Cordis 插件入口 + build_android_apk 工具定义
│ ├── build.js # 构建编排(检测/下载/ASCII staging/assemble/复制 APK)
│ └── download.js # 下载/解压/镜像回退/校验助手(仅用 Node 内置模块)
└── README.md
仓库里(不随 tarball 发布):
package1/
├── CHANGELOG.md # 每个版本的改动记录(每次发版必更新)
├── RELEASES.txt # 发布台账:维护约定 + 各版本 tgz 的 SHA-256
├── dsh-plugin-android-apk-<version>.tgz # 历史版本全部保留,不删除
└── test/
├── <最小 Android 工程> # settings.gradle / app/ …,用于真实构建验证
├── run-build.mjs # 无头驱动:脱离 DSH 直接跑 buildApk
└── progress-throttle.test.mjs # 下载进度与监听器泄漏的回归测试
test/、CHANGELOG.md、RELEASES.txt与历史 tgz 都随package.json的files白名单排除,不会打进 tarball;它们只存在于源码仓库。
常见问题
- 构建失败 / 工具没出现:安装后必须重启 DSH;
dsh plugin需要pnpm在 PATH。 - 工具报
userRender is not a function/ 注册失败 / 输出被拒:DSH 要求每个工具声明output.render(一个返回[{ type: "text", text }]数组的函数)。本插件自 0.2.1 起已内置; 若你看到该错误,说明装的是旧版本,升级到 ≥0.2.1。同理apks[]的staged字段也已在output.schema中声明(additionalProperties: false下缺字段会导致INVALID_TOOL_OUTPUT)。 - 装完 DSH 起不来(
1 required plugin did not activate/tools failed to import): 这是 0.2.0 及以前把@deepseek-ai/*写成dependencies导致的——pnpm 会往 profile 装一份 旧的dsh-tools,遮蔽宿主自己的tools行。升级到 ≥0.2.1(已改为peerDependencies), 并删除 profile 里的残留副本~/.dsh/profiles/<profile>/node_modules/@deepseek-ai/dsh-tools。 - 工程路径含中文/非 ASCII:插件会自动 staging 到 ASCII 临时目录构建(并给
gradle.properties加android.overridePathCheck=true),无需手动处理;staged SDK 会缓存复用,APK 仍复制回你的输出文件夹。 - 依赖下载超时:Gradle 依赖(AGP、AndroidX)从
dl.google.com拉取,网络不稳时可能超时; 插件使用下载文件夹里已缓存的依赖,可先手动gradle assembleDebug预热,或配置代理。 - 下载很慢:首次会拉取 JDK(约 180MB)+ cmdline-tools(约 150MB)+ Gradle(约 130MB),
后续复用插件
toolchain/里的缓存;依赖缓存也在该目录(gradle-user-home)。 - 插件升级后要重新下载工具链:
toolchain/在插件自己的目录里,而 pnpm 升级插件时会重建该目录, 所以升版本会丢掉缓存(约 460MB 需重下)。想让它跨版本存活,就在cordis.patch.yml里把downloadRoot指到一个固定路径(如D:/android-toolchain),或用工具参数downloadDir。 - build-tools 版本不匹配:插件从
sdkmanager --list里挑与 compileSdk 同大版本的最新 build-tools;可传compileSdk覆盖检测结果。 - 老工程需要 JDK 8/11:插件会先探测工程里的 AGP / Gradle 版本来推断所需 JDK(AGP 8、Gradle 8 → 17;否则 11):系统 JDK 满足就直接用,不满足才下载,且下载版本不会低于该要求(
jdkMajor只在需要下载时生效)。需要 JDK 8 的老工程请自行配好JAVA_HOME(插件最低要求 Java 11)。 - 非 Windows / Linux / Termux 宿主:构建路径已平台化,非 Windows 下 Java 用
java(which定位)、 sdkmanager 用sdkmanager脚本(自动chmod +x)、Gradle 用gradlew/gradle,下载按 平台取 Adoptium 三元组(Linux/macOS 为.tar.gz),解压回退链为unzip → python3 -m zipfile → tar。 社区已在 Termux (aarch64, Android 15) 上端到端跑通:ok: true、产出真实 APK(含classes.dex/AndroidManifest.xml等)。注意该实测用的是预装的 JDK 21 + SDK 34.0.4, Linux 上"从零下载 SDK"那条路径未被该次实测覆盖。
Comments
Loading…
Similar plugins
by CodeDice1024
DSH 插件开发助手:对话式引导,从零开始创建、测试、发布 DSH 插件
★ 0
TypeScript
Sep 4, 2026
dsh plugin --profile web add dsh-plugin-dev-assistantby builtin-pb
The single plugin you need for DSH — build, test, diagnose, and maintain DeepSeek Harness plugins and core.
★ 7
MIT
JavaScript
Sep 19, 2026
dsh plugin --profile web add dsh-developerby AJUbest
A DSH plugin that distinguishes official built-in DSH plugins and user custom plugins on the external interface.It can collect and manage all your previously created custom plugins 这是一个 DSH 插件管理插件,可在w
★ 6
MIT
JavaScript
Sep 9, 2026
dsh plugin --profile web add dsh-plugin-optimizationby jinwendijv
DSH 的应用启动器插件:自动扫描本机已安装的电脑应用,在侧边栏“设置”图标上方提供一键启动,像 Windows 开始菜单一样,扫描添加后可以点击启动应用
★ 0
MIT
JavaScript
Aug 27, 2026
dsh plugin --profile web add dsh-applauncherby AI-Scarlett
DSH Skill adapter for the build-dsh-plugin development workflow
★ 2
MIT
JavaScript
Sep 29, 2026
dsh plugin --profile web add dsh-build-pluginby KaiYuan0422
一个简单的dsh插件:可以创建一个直接双击启动dsh web界面的脚本,可以自定义图标
★ 0
MIT
JavaScript
Aug 15, 2026
dsh plugin --profile web add dsh-launcher