本文档面向 AI 编程助手 / agent:如何在任意 DSH 环境中部署本插件、理解它的加载与工作方式,以及如何维护、发布它。人类读者如需快速了解,请回到 README.md。
dsh-mobile-hanui 是一个 纯客户端 cordis 插件(client-only),为 DeepSeek Harness(DSH)的 Web GUI 提供移动端(窄屏)适配。它:
- 不包含 服务端(Node host)逻辑,不注册工具,不改动 DSH 核心源码
- 生效条件:浏览器视口
max-width: 1023px(即手机 / 窄窗口) - 桌面端完全不受影响(所有样式都受移动端断点 +
html.dsh-mobile-shell作用域保护)
dsh-mobile-hanui/
├── src/
│ ├── client.js # 客户端 bundle:window.__ModuleLoader__.load 注册,全部移动端逻辑
│ └── index.js # host 空桩(apply 为空;仅满足 client-modules 扫描契约)
├── cordis.patch.yml # bundle patch:只插入一个空的 host entry,供 client-modules 扫描
├── package.json # dsh.bundle.patch + dsh.client 声明
├── README.md # 给人看的简介
└── AGENTS.md # 本文件
- 一个运行中的 DSH
webprofile(dsh web启动的服务) - 该 profile 的标准 bundle 已包含
@deepseek-ai/dsh-client-runtime与@deepseek-ai/dsh-client-ui-layout(标准@deepseek-ai/dsh-web-app自带的,无需额外安装) - 无 npm 依赖、无构建步骤、无 postinstall、无需 API Key
-
进入 profile 目录:
cd ~/.dsh/profiles/web
-
安装包:
pnpm add dsh-mobile-hanui
-
编辑
~/.dsh/profiles/web/package.json,在dsh.profile.bundles数组中加入包名: -
装依赖并重启服务:
cd ~/.dsh/profiles/web && pnpm install sudo systemctl restart dsh-web # 或对应进程管理器
-
验证:用手机或浏览器开发者工具(视口 ≤1023px)打开 DSH 网页,移动端布局自动生效。
-
克隆仓库:
git clone https://github.com/Z-6354/dsh-mobile-hanui.git /data/dsh-mobile-hanui
-
在 profile 的
package.json里用link::"dependencies": { "dsh-mobile-hanui": "link:/data/dsh-mobile-hanui" }
-
pnpm install→ 重启服务(同方式 A)。
dsh plugin --profile web add dsh-mobile-hanuidsh plugin add 会转发 pnpm add,并自动把「解析到 dsh.bundle 的依赖」加进 bundles。
package.json的dsh.client声明platform: "web"和inject: [...]。- DSH 的
client-modules扫描器读取各 bundle 的dsh.client,把本插件写入 boot manifest(window.__DSH_BOOT__的 entries),并 serve/plugins/dsh-mobile-hanui/client.js。 src/client.js通过window.__ModuleLoader__.load({ id: "dsh-mobile-hanui", factory })注册;factory 内require('react')、导出{ apply, inject }。
本插件是 client-only,src/index.js 的 apply() 为空。cordis.patch.yml 只插入一个空 host entry(id: dsh-mobile-hanui-shell),作用是让 client-modules 能扫描到包的 dsh.client。不要删除这个空 entry,否则客户端 bundle 不会被注入。
- 全部视觉改动位于
src/client.js内的一大段内联 CSS 字符串(const CSS = ...),通过ensureStyle()写入<style data-plugin="dsh-mobile-hanui">。 - 所有规则都在
@media (max-width: 1023px)内,且选择器都带html.dsh-mobile-shell前缀;MobileChrome组件在useMobile()判定为手机时往<html>加dsh-mobile-shellclass。 - 因此桌面端(宽视口)或未激活时,这些规则完全不生效。
MobileChrome 是核心 React 组件,通过 ctx.slots.inject('shell.overlay', ...) 注册到 shell.overlay slot,注入:
- 可拖拽 FAB(
.dshMobMenu)+ backdrop(.dshMobBackdrop) - 若干副作用:focus 抑制、上滑自动加载历史、子代理目录/提问面板/设置面板适配、tooltip 隐藏等
- 直接改
src/client.js,然后sudo systemctl restart dsh-web(服务会按文件内容重新计算 rev 并 serve 新 bundle)。 - 无需构建(纯 JS)。
-
改完并测好后,bump 版本并自动生成 tag:
npm version patch # 或 minor/major注意:不要用
--no-git-tag-version(曾因此漏打 tag,导致github:owner/repo#vX.Y.Z安装 spec 失效)。 -
提交并推送:
git push origin main git push origin --tags
-
发布 npm:
npm publish --access public
注意:npm 不允许覆盖已发布的版本号;若该版本号已误发,必须 bump 到下一个版本再发。
- 不要改动 DSH 核心插件(如
dsh-client-runtime的maxMessages),那些改动不随本包分发、DSH 升级或重装会丢失,且违反「只改插件本身」的原则。 - git tag 必须随版本 bump 一起打并 push(
github:owner/repo#vX.Y.Z安装 spec 依赖 tag 存在)。 npm publish需要具备 bypass 2FA 权限的 token。- 直接改 npm 包
node_modules里的编译产物(lib/client.js)的改动,不会被 git 追踪,重装即丢。
- 移动端布局没生效:确认视口 ≤1023px;在页面源码里搜
dsh-mobile-hanui,boot manifest 里应有对应 entry。若无,说明 bundles 没生效,检查pnpm install+ 重启。 - 客户端 bundle 404:profile 的
node_modules里必须有dsh-mobile-hanui的 symlink(link:或 npm 装出来的)。 - 桌面端被影响:理论上不可能(断点 + 作用域保护);若发生,检查是否误改了
dsh-mobile-shellclass 的注入逻辑。
- URL 加
?mobileShell=0 localStorage.setItem('dsh-mobile-shell', '0')后刷新
{ "dsh": { "profile": { "bundles": [ "@deepseek-ai/dsh-base", "@deepseek-ai/dsh-web-app", "dsh-mobile-hanui" ] } } }