网页版界面的手机外壳:侧栏改为覆盖式抽屉、点会话自动收起,设置面板改全屏单列,正文排版按手机阅读距离重调。
安装
# GitHub 源码(首次需按提示配置 allowBuilds 构建授权后重试)
dsh plugin --profile web add github:AliceLJY/dsh-thumb
装任何插件都等于在你的机器上跑第三方代码,权限和你本人一样大——能读你的文件、用你的凭据、访问网络,工具审批管不到它。GitHub 来源的插件还会在安装时执行构建脚本——pnpm 默认拦截,所以安装可能停在 ERR_PNPM_GIT_DEP_PREPARE_NOT_ALLOWED 或 ERR_PNPM_IGNORED_BUILDS;dsh 会打印出需要添加的确切键名,把它加进该 profile 的 pnpm-workspace.yaml 的 allowBuilds 下,重跑一次即可装上。放行构建本身就是一次信任判断:请只安装可信来源,并尽量锁定 commit(github:owner/repo#sha)。
README
给 DeepSeek Harness(dsh)网页版做的手机外壳。侧栏从「挤压聊天区」改成「覆盖式抽屉」,点会话自动收起,设置面板改全屏单列,正文排版按手机的阅读距离重调。桌面端一点不碰。
个人自用工具,按原样发布。 是照着一个人的手机、一个 dsh 版本(
0.1.0-rc.6)写的,不承诺维护、不承诺响应 issue。dsh 升级后失效的话,改src/client.js顶部LOCATORS那四条定位器就行,是分钟级的事。
为什么需要它
dsh 的网页界面在手机上首屏是正常的——侧栏自动收成 56px 图标条,输入框完整。问题全在侧栏展开之后,而那正是手机上切会话的必经路径。
实测(iPhone 14 Pro 视口 393×660,dsh 0.1.0-rc.6,装本插件之前):
| 场景 | 改造前 | 改造后 |
|---|---|---|
| 收起态(图标条) | 正常 | 不介入,原样 |
| 侧栏展开 | 侧栏占 71% 屏宽,挤压聊天区到 113px | 抽屉覆盖,聊天区 393px 满宽 |
| 点会话之后 | 侧栏不收,一直卡在 113px 窄缝 | 自动收起 |
| 关闭抽屉 | 只能手动点收起按钮 | 点遮罩任意处即可 |
| 设置面板 | 800px 两列硬塞,英文逐词换行,选择器切出屏幕 | 全屏单列,文字正常换行,选择器回到屏内 |
| 设置面板被切元素 | 7 处 | 1 处 |
| 正文总高(三轮会话) | 610px,按桌面阅读距离排的 | 490px,少五分之一 |
根因不是 bug,是上游的显式契约。@deepseek-ai/dsh-client-ui-layout 的列求解器注释写得很清楚:
The sidebar never concedes: its rendered width is always the drag preference (or the collapsed rail), and center absorbs any remaining deficit as the last resort.
配合 SIDEBAR_DEFAULT = 280,在 393px 视口上算出来就是 393 − 280 = 113。让步链是「先缩详情栏 → 再关详情栏 → 最后中间栏吃掉全部亏空」。在窄的桌面窗口上这很合理(还剩几百 px),在手机上就不行了。
装 / 卸 / 临时关
# 装
dsh plugin --profile web add github:AliceLJY/dsh-thumb
# 确认 ~/.dsh/profiles/web/package.json 的 dsh.profile.bundles 里有 "dsh-thumb",然后重启服务
# 卸
dsh plugin --profile web remove dsh-thumb
# 同样确认 bundles 数组里已移除,再重启
没有 npm 包:dsh plugin add 把参数直接交给 pnpm,所以 github: 规格能直接装仓库。冷存储下实测 8.9 秒,dsh 会自己把它追加进 dsh.profile.bundles。
想在本地改着用?同一条命令换成路径即可:
dsh plugin --profile web add link:/绝对路径/dsh-thumb
⚠️ 卸载/回滚要两件一起做:package.json 和 node_modules 里的 link。只还原 package.json 的话,下次 pnpm add 会看到 link 还在、判定 "Already up to date",不写任何东西也不报错——看起来装上了,实际没有。
临时关闭,不用重启服务:
- 地址后加
?thumb=0 - 或控制台
localStorage.setItem('dsh-thumb','0')后刷新
它跟 GitHub 上那些同类插件的区别
同期社区有十几个 dsh 移动端项目,做同一件事的插件的通行写法是在 CSS 里硬编码 dsh 的 class(pI_x6G_sidebarCol、Md3f7G_scroll 这种)。那些 class 是 CSS Modules 构建时生成的,dsh 每次重新构建就全变,插件随之静默失效——样式不生效、页面还在、控制台不报错,你只会觉得"今天怎么又难用了"。
样式表里不放任何宿主 class 名(源码注释里出现过两次,是作为"不该硬编码成什么样"的反例)。做法是运行时按语义后缀(sidebarCol 这半截来自上游源码的变量名,不随构建变)定位一次,给节点打上自己的 data-thumb 属性,样式表只认这些属性。上游要是真改了变量名,坏的是一个定位器,在一个地方、能直接查出来;不会变成满地样式无声失灵。
行为上也尽量走官方接口:关抽屉调的是 ctx.layout.toggleSidebar()(上游 ILayout 的公开方法,ui-sidebar 自己也用它),不是去模拟点击某个按钮。
作用域
布局类规则只在两个条件同时成立时生效:视口 ≤1023px(对齐上游的 SIDEBAR_AUTO_COLLAPSE = 1024,避免两套断点打架)且侧栏被手动展开了。56px 图标条那个状态完全不碰——它本来就是好的。
平板尺寸下抽屉化还值不值?
这份文件早先的版本猜测「到了平板尺寸抽屉化未必还是改善」,并建议把断点降到 767px。实测下来,那个猜测是错的。
真正该看的是点完一个会话之后的状态——因为切换会话必须走这条路。原生行为是侧栏赖着不走,正文停在 宽度 − 280;本插件会自动收起它,留下 56px 图标条,正文是 宽度 − 56:
| 视口宽度 | 原生 | 装了本插件 | 收益 |
|---|---|---|---|
| 393px | 113px | 337px | +198% |
| 480px | 200px | 424px | +112% |
| 604px | 324px | 548px | +69% |
| 768px | 488px | 712px | +46% |
| 900px | 620px | 844px | +36% |
| 1023px | 743px | 967px | +30% |
这张表可以用 node test/measure-widths.mjs 重新生成;那个文件里也写清了为什么量的是「最后剩给你多宽」而不是「抽屉盖住了多少」——后者正是第一次量错的地方。
收益随宽度递减,这符合预期——但在整个支持区间里从未反转。降断点等于在它本该起作用的尺寸上,关掉一个仍值 30–46% 的东西。1023px 这个断点保持不变。
正文密度规则是唯一有意的例外:它在 ≤1023px、抽屉关着的状态下生效,因为读正文本来就是抽屉关着的时候。实测那个会话从 610px 压到 490px,其中 60px 只来自消息之间的间距(16px → 10px),这一项没有任何交互代价。正文字号 16px/28px → 14px/21px,操作按钮 28px → 24px;按钮本来就低于 iOS 建议的 44px 触摸目标,所以最后这项是个权衡,样式表顶部的 --thumb-hit 可以调回去。
桌面端已验证零变化:侧栏 280px、中间栏 1160px、position: static、无遮罩、设置面板仍是 800px 两列。
已知限制
- hover tooltip 仍可能溢出右边缘(悬停工作区行时那个黑色卡片)。有意不修:它的 class 语义(
_card/_copyable)太泛,稳妥的修法得在每帧扫描所有position: fixed浮层再逐个夹回视口,误伤面不明,而它只是视觉瑕疵、不挡任何操作。真要修的话,正确入口是上游给 tooltip 加触屏判断,不是从外面兜。 - 实测过 393、480、560、604、640、700、768、900、1023px 以及桌面 1440×900,数据见作用域一节。手机尺寸是每天在用的,其余只是量过一次,没有长期使用。
- 设置面板的导航项仍是竖排,没有变成横向滚动条——那条
flex-direction: row打在了一个并非真正承载这些项的容器上,结果是面板顶部多占一点垂直空间。有意不追:面板已经从「没法用」变成「能用」,再去精确定位那一层属于打磨不属于修复。 - AI 回复下面那排操作图标仍是 28px,只有用户消息那侧压到了 24px。它套在另一层 flex 容器里,
height、align-self、min-height三样都推不动它,而扫遍样式表也找不到任何一条给这些 class 设过高度的规则——也就是说撑住它的东西不在「按 class 名找规则」这个探测范围内。有意不追:三轮会话上只值 12px,约占正文总高的 2%。 - 上游改了列布局的实现方式就得跟着改。定位器在
src/client.js顶部的LOCATORS,四条,改起来是分钟级的事。
验证
node test/smoke.mjs # 21 项断言,需要一个跑着的 dsh
脚本在手机视口和 1440×900 各驱动一遍真实 dsh:定位器打标、抽屉打开时聊天区是否占满宽度、四个密度数值、作用域是否越界、平板宽度、关闭开关,以及桌面回归(断言桌面正文仍是 16px)。其中一条不是查属性而是端到端的——同一段会话加载两次、一次带 ?thumb=0,要求本插件那次的正文至少矮 15%。
到目前为止它接住了两个真回归,两个都值得记下来。
关闭开关,第一次跑就红了。?thumb=0 一直以来只关掉了 React 组件,在密度规则落地之前这就够了——那时每条规则都挂在一个只有活组件才会设置的抽屉属性上。密度规则是抽屉关着也生效的,样式表本身就成了承重件,开关够不到它。已在 ensureStyle / stampFrame 里直接检查开关修掉。
作用域越界,而这个测试没接住,是从手机上报回来的。中间栏挂的不只是对话,还有轨迹视图,而轨迹页的工具栏是一排文字按钮。[class*="_actions"] > button 把它们统统压成了 24px 见方,Duration / Turns / Calls 叠成一团没法读。现在每条密度规则都走 FLOW 作用域——它靠"这一列里装着消息条目"来认对话列,而不是靠 class 名。真正的教训不是选择器写宽了,而是一套只打开过一个 tab 的测试,会在隔壁视图坏掉的时候一路绿灯。所以补了那条越界断言,并且把 bug 放回去验过它确实会红、还会点名那三个按钮。
复现那个的注意事项:手机宽度下 Playwright 点不动轨迹 tab。先在桌面尺寸点开,再把视口缩小——同一个已挂载的视图、窄屏布局,中间不发生跳转。
跑出来的截图没有随仓库发布——上面有真实的工作区名和会话标题。下面三个坑才是复现时真正需要的东西。
复现时会踩到的三个坑,一并记在这:
- ESM 不读
NODE_PATH—— 全局装的 playwright 要用绝对路径引入,而且它是 CommonJS,得走 default import。 - Chrome 会吃系统代理,
ts.net地址直接超时 —— 走http://127.0.0.1:3080加--no-proxy-server。 waitUntil: 'networkidle'永远等不到 —— dsh 有常驻实时连接,用domcontentloaded加固定等待。
开发笔记
两个坑记在这里,因为都属于"看起来在别处、实际在自己身上"那类:
插件不激活、整页白屏。 package.json 的 dsh.client.inject 和 client.js 导出的 inject 同名同形但语义不同:前者是包名(模块加载顺序),后者是 cordis 服务名(['slots', 'layout'])。把后者写成包名,插件会一直 pending,外壳报 web boot: 1 entry did not activate,而整个页面渲染不出来。参照 @deepseek-ai/dsh-client-ui-sidebar 的 inject 值就对了。
永远关不掉的抽屉。 判断抽屉是否展开,一开始读的是侧栏的渲染宽度(>56px 即展开)——而抽屉 CSS 恰恰把侧栏钉在 320px。判据被自己的副作用污染,于是它永远为真,收起按钮、遮罩、自动收起全部"失灵",看起来像 ctx.layout.toggleSidebar() 在窄屏下不工作(它其实一直是好的)。现在读的是 AppFrame 写在 frame 上的 inline grid-template-columns 第一列——那是上游的意图,本插件不碰。规矩:不要用一个自己会覆盖的量去做判据。
License
MIT
链接
同类插件
zhu1090093659/dsh-web#packages/dsh-task-board★ 8597
侧边栏多列任务看板:卡片交给真实 DSH 智能体会话执行,支持 cron 定时(Host 侧到点执行,关浏览器也生效)。
zhu1090093659/dsh-web#packages/dsh-web-all★ 8597
DSH Web UI 插件与皮肤合集:任务看板、git 图、右侧面板、远程移动端 UI、桌宠、实时 token 统计与皮肤中心。
MeteorNOX/DeepSeek-Balance-Whale-Widget★ 4424
右下角常驻的小鲸鱼挂件:余额、今日已用与每轮对话消耗(含峰谷价),余额预警与今日预算的泡泡内容都可编辑;泡泡点击序列模块化自定义,支持并列加权 A/B、随机台词与随机图片;内置 30+ 厂商模板(OpenAI / OpenRouter / Kimi / 硅基流动 / 方舟 / 智谱 / MiniMax 等),按模型查余额与订阅额度;另有任务结束音效、导入音频、自定义角色与资源管理。数据全在本机,无遥测。
ccch1mneyyy/dsh-TUI★ 4268
Claude Code 风格全屏终端 UI:像素鲸鱼顶栏、实时工作状态行、思考流式展开。
omdsh-dev/DSH-better-sidebar★ 4098
侧边栏完整工作台:内置文件渲染编辑、终端、Git 与子代理,支持三方插件注册新 Tab。
Devin-AXIS/deepseek-design#deepseek-idesign★ 1445
可视化设计工作室,支持网站、App 原型、海报、信息卡、报告和杂志的模板创建、元素编辑、选区级 AI 草稿衔接与导出。
社区评论
评论公开保存在 GitHub Discussions。加载评论会连接 GitHub 和 Giscus;发表内容需要 GitHub 账号。