dsh-mobile-ux
面向手机端访问体验的 DeepSeek Harness UI 优化插件(纯客户端)
一个包、零配置:把 DeepSeek Harness 网页版在手机宽度下的体验从头打磨一遍——响应式抽屉布局、字号/间距适配、≥44px 触控目标、按钮/菜单/表格移动端交互、安全区适配。桌面宽度显示与使用完全不受影响。
这是什么
DeepSeek Harness 网页版默认按桌面三列布局设计,在手机宽度下会出现:侧栏挤压主内容、正文 16px 偏大、触控目标过小、宽表格/代码块把横向滚动条推给视口、设置页两列布局留大片死区等问题。
dsh-mobile-ux 是一个纯客户端插件(宿主侧零逻辑):在窄屏(max-width: 1023px,与 shell 的 SIDEBAR_AUTO_COLLAPSE 一致)自动注入一套移动 UI 优化层;在宽屏(≥1024px)所有移动控件一律隐藏,桌面布局原样保留。
它基于 dsh-pocket 的「单包客户端插件」组织方式,但移动 UI 层为从零实现(不依赖 dsh-web-mobile)。既可单独使用,也可与 dsh-pocket 并存——后者继续负责「扫码远程访问」,本插件只负责「手机上的界面更好用」。
安装
前提:已装好 DeepSeek Harness(dsh CLI)。
# 从 GitHub 直装
dsh plugin --profile web add "github:wangyuanchuan2022/dsh-mobile-ux" -w
# 重启 dsh web 生效
npx @deepseek-ai/dsh web
本地开发/试用可用 link 安装(不依赖网络,指向本地路径):
dsh plugin --profile web add "link:/绝对/路径/dsh-mobile-ux" -w提示 1:手机扫码访问本身由 dsh-pocket 提供(局域网/公网二维码),本插件只负责手机端 UI。
提示 2:
dsh-pocket自带一套移动抽屉层;二者可互相替代,不建议同时启用——同时安装会出现两套移动控件。若已装dsh-pocket且想单用本插件的移动 UI,可先dsh plugin --profile web remove dsh-pocket -w(代价是失去扫码远程访问),或接受两者并存。
✨ 优化点逐项说明
所有规则都只作用于窄屏(max-width: 1023px);宽屏(min-width: 1024px)下移动控件全部 display:none,桌面布局不受任何影响。
| # | 优化点 | 实现方式 | 效果 |
|---|---|---|---|
| 1 | 响应式抽屉布局 | AppFrame 打上 data-mobile-ux="frame" 标记;三列网格重排为 minmax(0,1fr) 0 0,把中心列拉回第 1 轨;侧栏列改为绝对定位的左侧抽屉(translateX(-105%) 收起 / transform:none 展开,max-width:84vw) |
侧栏不再挤压主内容,会话区域全宽;抽屉滑入滑出,点遮罩/点外部/点导航项自动关闭 |
| 2 | 字号与间距适配 | 正文容器 font-size:15px、左右留白从 32px 收紧到 16px;去掉桌面滚动条占位 scrollbar-gutter 与滚动条 |
一屏可读更多内容,列精确居中,无桌面滚动条挤偏移 |
| 3 | 触控目标 ≥44px | FAB 直接 44×44px;头部目录开关 28px 视觉 + ::after{inset:-8px} 扩展命中区至 44×44px;设置页关闭按钮 40px 圆形基座;外观卡 min-height:44px |
符合移动端可用性基线(Apple HIG / Material 建议 ≥44px),点按不易误触 |
| 4 | 头部/菜单移动端交互 | 会话头部注入目录开关(conversation.session.header.actions);hero/空白阶段注入浮动目录按钮 FAB(shell.overlay);backdrop 纯视觉压暗(pointer-events:none),关闭交给 document 级「抽屉外点击」监听 |
无论有无会话都能一键唤出目录;遮罩不抢点击,抽屉内点击不被吞掉 |
| 5 | 设置页下沉为 sheet | 桌面两列设置对话框在窄屏改为近全宽 sheet(left:8px; width:calc(100vw - 16px));导航 tab 折成 3 列网格;选项行「标题+描述在上、控件在下」堆叠;外观三卡改横向三连;工具栏两端展开 |
设置页在手机上无死区、无横向溢出、tab 全部可见,实测 390px 下 width:374px 完整显示 |
| 6 | 宽内容防溢出(表格/代码块) | 消息区内的 table、pre 设 max-width:100%; overflow-x:auto;消息动作行 overflow:hidden + 省略号 |
长表格/长代码/长串只在自身容器内横滑,绝不把横向滚动条推给视口 |
| 7 | 会话统计行横滑 | 客户端按文本锚定 turns/steps/LLM/TTFT/cache 那行,打 data-mobile-ux="stats",CSS 排成固定 28px 高、横向滚动的单行条(含 TPS 并入) |
全部指标通过滑动触达,行高不涨、不换行、不省略 |
| 8 | 输入区优化 | 模型胶囊改为可收缩(flex:1 1 auto)、权限胶囊保持自然宽度,避免权限胶囊被挤成 15px;hero 空态 textarea 收缩为一行 |
输入区底行在窄屏不再溢出/重叠,hero 空态更紧凑 |
| 9 | 会话头部布局 | 头部排成 [目录开关][会话标题][模式徽标] 一行;「导出会话日志」胶囊从头部搬迁到抽屉底部(功能不丢) |
头部信息密度合理,窄屏不再被长胶囊顶破 |
| 10 | 安全区适配 | 客户端把 viewport meta 改成 viewport-fit=cover,CSS 用 env(safe-area-inset-top) 把内容推到状态栏/刘海之下;theme-color 跟随主题底色 |
刘海屏/状态栏不遮挡内容,状态栏读起来像 UI 的一部分 |
| 11 | 双击缩放抑制 | html,body{touch-action:manipulation} + 旧 iOS gesturestart 兜底 |
消除双击缩放与 300ms 点击延迟,保留平移与捏合缩放 |
| 12 | 降级/可访问性 | 抽屉支持 Escape 关闭(有模态框时让位);prefers-reduced-motion 下关闭动画;控件带 aria-label/focus-visible 焦点环 |
键盘与辅助技术可用,动效敏感用户不受影响 |
✅ 验收实测
在隔离 DSH 实例(dsh web --port 3090)上用无头 Edge(CDP)实测:
| 视口 | 横向滚动条 | frame 改写 | 移动控件 | 触控交互 |
|---|---|---|---|---|
| 桌面 1280×800 | ✅ 无(scrollWidth==1280) |
✅ 未改写(桌面原样) | ✅ 全部隐藏 | — |
| 手机 390×844 | ✅ 无(scrollWidth==390) |
✅ 抽屉布局生效 | ✅ FAB 44×44 可见 | ✅ 触摸/鼠标/点击均能打开抽屉 |
| 手机 430×932 | ✅ 无(scrollWidth==430) |
✅ 抽屉布局生效 | ✅ FAB 44×44 可见 | ✅ |
- 设置页 sheet 实测:390px 下
x:8, width:374, right:382,无横向溢出,导航 tab 完整可见。 - 触控目标实测:FAB
getBoundingClientRect()= 44×44px,命中区满足 ≥44px 基线。
复现方式见下方「开发」;输出报告与截图落在 .verify-out/(已 gitignore)。
🗂 架构(单包,纯客户端)
| 文件 | 说明 |
|---|---|
lib/index.js |
宿主侧入口:仅导出合法的 cordis 插件标识(name/inject/apply),无任何宿主逻辑,作用是让 Loader 建立 fiber 以编入客户端图谱 |
cordis.patch.yml |
dsh.bundle manifest:把插件插入 profile bundle 层 |
client/index.jsx |
客户端入口:导出 apply/name/inject,挂载移动 UI 层 |
client/build.mjs |
esbuild 打包:client/index.jsx → client/client.js(window.__ModuleLoader__.load 包装) |
client/mobile/mobile.css.ts |
移动端样式表(从零实现,仅用稳定框架契约选择器) |
client/mobile/mobile-apply.tsx |
客户端 apply:注入样式 + 手机 chrome + 统计行标记 + 三个 slot 组件 |
client/mobile/MobileNavToggle.tsx |
会话头部目录开关 |
client/mobile/MobileNavOverlay.tsx |
shell 覆盖层:frame 标记 + backdrop + FAB + 抽屉交互 |
client/mobile/MobileDrawerFooter.tsx |
抽屉底部「导出会话日志」 |
client/mobile/locales.ts |
mobileUx 词典(zh/en) |
scripts/verify-mobile.mjs |
无头 Edge + CDP 移动验收脚本(桌面/手机宽度 + 触控交互) |
scripts/verify-settings.mjs |
设置页 sheet 验收脚本 |
test/*.test.js |
单元测试(host 契约 / package 契约 / locale 一致 / CSS 契约 / bundle 冒烟) |
🛠 开发
npm install
npm run build:client # 改 client/ 后重新打包
npm test # 单元测试(19 项)
移动端实测(需要一个隔离的 dsh web 实例):
# 终端 1:隔离实例(用独立 DSH_HOME 与端口,不影响日常实例)
$env:DSH_HOME = "D:\path\to\.dsh-test" # Windows PowerShell
dsh plugin --profile web add "link:D:/path/to/dsh-mobile-ux" -w
dsh web --port 3090
# 终端 2:跑验收脚本(无头 Edge + CDP)
node scripts/verify-mobile.mjs
node scripts/verify-settings.mjs
🤝 致谢与关系
- 插件组织方式(单包客户端插件、
dsh.client/cordis.patch.yml/__ModuleLoader__打包)参考 dsh-pocket(GPL-2.0)。 - 移动 UI 层为独立从零实现,未复用 dsh-web-mobile 代码;二者可互相替代(不建议同时启用两个移动抽屉层)。
📄 License
GPL-2.0 —— 自由软件许可:可自由使用、修改、分发,但修改版必须同样以 GPL 开源并保留版权声明。
有问题?欢迎反馈:到 GitHub Issues 告诉我们。
No comments yet. Be the first to write one.