界面精简(dsh-ui-fit)
一个插件,管三件事:左栏导航折叠、输入条精简、手机端密度压缩。 三块可以分别开关,关掉哪一块,那一块就完全回到宿主原样——不是把按钮藏起来,是那一段 样式真的失效。
合并前它们分散在三个独立插件里,各管一处界面,却各自往 <html> 上挂自己的开关属性、
还互相借 CSS 变量,卸载其中一个另一个就会退化。现在只有一份样式表、一个根属性、一套变量。
安装
要求 DSH >= 0.2.1-rc.5、Node ^22.19.0 || >=24.0.0。
方式一:Web 界面(最简单)
左栏「插件」→ 右上角安装框 → 粘贴 github:HotAntOne/dsh-ui-fit → 安装 → 打开开关。
方式二:命令行
dsh plugin 是把参数转发给 profile 目录里的 pnpm,所以用 add:
dsh plugin --profile web add github:HotAntOne/dsh-ui-fit
装到别的 profile 就换 --profile 的名字(desktop / tui / …)。装完刷新页面(Ctrl+R),
不需要重启 DSH。卸载:
dsh plugin --profile web remove dsh-ui-fit
方式三:本地源码
git clone https://github.com/HotAntOne/dsh-ui-fit
dsh plugin --profile web add /绝对路径/dsh-ui-fit
本仓库同时是一个可发布的 npm 包,
npm publish之后也能dsh plugin --profile web add dsh-ui-fit。 发布前请先把package.json里的author改成你自己的名字。
装完发现插件"消失"了?先跑一次自检
本插件用 link: 方式装(方式三)时,Node 会先把入口解析成真实路径(源码目录),再从源码
目录向上找 node_modules。如果源码目录那条链上没有 node_modules,index.js 里
import '@deepseek-ai/schemastery' 就会失败,Loader 把这一行标成 inactive——表现是
插件整个不见(页脚按钮、设置页都没了),但 package.json、bundles、cordis.patch.yml
全都是好的,从界面上完全看不出是缺依赖。
cd /绝对路径/dsh-ui-fit && npm run setup
它做三件事:用 Node 的规则解析一次;解析不到就找本机已装好的 profile 链接过去(开发机 自愈);都不行退出码 1 并打印该跑的命令。不会静默通过。
用 dsh plugin add(方式一、二)安装时 pnpm 会按 dependencies 正常装依赖,不需要这一步。
装完之后在哪
设置(左下角账号菜单 → 设置)→ 左列「界面精简」,三个开关:
| 开关 | 默认 | 管什么 |
|---|---|---|
| 左栏导航 | 开 | 把「插件、插件市场、上下文洞察、任务看板、SSH」这些全局行收进「更多」,或压矮行高 |
| 输入条 | 开 | 藏掉语音按钮,模式 / 计划 / PUA 三个控件改纯图标;输入条变窄时自动收紧 |
| 手机端密度 | 开 | 只在窗口宽度 ≤ 899 像素时生效,压缩手机上的各类留白 |
默认全开,与合并前完全一致。
为什么设置页要自己写:宿主只按
Configschema 生成表单定义(Config.listConfigs里status: 'schema'),不会把它变成设置面板里的一节——@deepseek-ai/dsh-settings的 README 明写「no shipped client does so yet」。所以本插件自己注册了settings.section(iddsh-ui-fit、order 18),页面里的开关直接写本插件的配置命名空间,写成功后宿主广播, 样式与页面同时刷新。这一节不受任何开关管辖,否则关掉之后就再也开不回来。
一、左栏导航
左栏有六行全局面板(插件、插件市场、上下文洞察、任务看板、SSH、更多),工作区列表被挤到 很下面。这个功能把竖直空间还回来,有三种状态,点左栏最底部那颗三横线图标循环切换:
| 状态 | 外观 | 颜色 | 说明 |
|---|---|---|---|
| 标准 | 三行等距 | 三级文字色 | 宿主原样 |
| 紧凑 | 三行更近 | 二级文字色 | 每行矮 6px、去掉多余行距,约还回一行高度 |
| 收纳 | 一行 + 尖角 | 品牌色 | 除「更多」外的面板行全部隐藏,都进「更多」菜单 |
收纳态下「更多」菜单里会列出插件管理 + 每一个被收起的面板,所以没有面板会变得不可达。
三态存在哪:localStorage 的 dsh-ui-fit:nav,每浏览器各存一份。理由是这个选择
是「这一屏我临时想怎么摆」,属于设备级偏好,不该跟着账号同步到别的设备。
页脚那颗柱状图图标是「对话宽度挡位」的入口。宽度挡位插件(dsh-width-tiers)只往
shell.overlay 渲染,注册不了页脚槽位,所以这里做了一颗代理按钮:点它转发一次点击给它自己
的触发器。转发延后一个任务——那个插件用 document 级 click 监听关菜单,同步转发会让菜单
在同一次手势里开了又被当成「点了外面」立刻关掉。
二、输入条
四条纯样式规则:
藏掉语音按钮。
dsh-better-input那个麦克风按钮在这个环境里一直失败,直接不显示。 它的尺寸写在行内样式里,所以这条必须!important。徽章改纯图标,并统一到宿主的尺寸节奏。PUA、权限模式、计划三个控件原来是「图标 + 文字」, 改成只有图标;同时按钮一律 28px、图标一律 14px——宿主自己的「+」和右侧两颗就是 28px 按钮 + 14px 图标,原来 PUA / 权限模式是 36px(PUA 图标 18px),并排看明显大一截。 两个数抽成
--dsh-fit-btn/--dsh-fit-icon,挂在[data-composer-card]上,改一处即齐。:has()守卫保证:宿主若没给某个权限值渲染图标,那个控件就保留文字,不会变成空圆圈。窄行收紧。输入条自身实测宽度 < 560px 时:间距从 8px 收到 4px、内边距减半、 输入卡铺满宽度、并解掉
dsh-mobile在 720px 以下强加的 44px 触控下限。 只收间距,不收按钮尺寸——桌面和窄屏都用同一套 28px / 14px,否则同一排里会出现 34px 与 28px 混排。为什么用实测行宽而不是媒体查询:媒体查询问的是「窗口多宽」,折行只关心「这一行多宽」。 手机壳里有 56px 轨道、外层内边距、抽屉,这两个数并不相等。地址后加
#fit-debug可以 看到真实测量值。
三、手机端密度
只在窗口宽度 ≤ 899px 生效,桌面窗口下这一段完全不打标记。十组规则:
| # | 位置 | 做了什么 |
|---|---|---|
| ① | 每轮费用行 | 压成一行可省略的 11px 小字 |
| ② | 底部状态条 | 只留「上下文占用」与「缓存命中」,去掉计时、费用明细入口、本会话合计 |
| ③ | 顶部工具条 | 解掉宿主 76px 的固定下限,按钮收到 32px |
| ④ | 消息操作行 | 按钮收到 22px,图标 13px;第三颗之后(格式、分享)收起 |
| ⑤ | 助手状态行 | 「已完成,用时 X」与「深度求索中」压到 24px |
| ⑥ | 对话标签栏 | 去掉 10px 上边距,标签改横向滚动,不再逐字换行 |
| ⑦ | 顶栏溢出 | 标题行横向滚动、收掉宿主的推挤边距,三块徽标不再互相压住 |
| ⑧ | 上下文百分比 | 单独下移 1px(宿主那颗是「14px 圆环 + 13px 文字」,与 12px 的胶囊基线不同源) |
调那 1px:改 --dsh-fit-context-shift,默认 1px。
四、验证
node --check client.js # 语法
node test-client.mjs # 离线冒烟:三段规则、三态循环、开关失效、清理
node check-hooks.mjs # 宿主升级后体检:CSS 钩子还在不在
check-hooks.mjs 会扫 asar 里和 profile 里所有 .js,逐个确认本插件依赖的宿主钩子
(data-composer-dock、data-conversation-tabs、_titleRow 之类)是否还存在。宿主升级
后跑一次,退出码 1 就说明有钩子改名了,对应规则会静默失效。
人工验证清单:
- 左栏底部有两颗小图标;点三横线那颗,面板行依次变成紧凑、收纳、标准。
- 输入条右侧的麦克风图标不在;PUA / 权限 / 计划是纯图标。
- 手机(或窗口缩到 899px 以下)上:每轮费用行变矮、底部只剩两个读数、消息操作行只剩三颗。
- 把「左栏导航」关掉 → 面板行立刻回来、两颗页脚图标消失、样式表里那段规则失效。
- 把「输入条」关掉 → 麦克风回来、徽章恢复文字。
- 把「手机端密度」关掉 → 手机上的一切恢复原样。
- 关掉任意一个开关后按 Ctrl+R 刷新 → 状态保持(开关已落到 profile 的
cordis.patch.yml)。 - 关掉导航后仍能从设置页把开关打开 → 设置页自身不受开关影响。
五、实现要点
- 一个文件、三段样式。
client.js里CSS数组按「变量 → 导航 → 输入条 → 手机密度」 排列。手机密度在最后,所以窄屏规则天然压过前两段,与三个插件共存时的层叠结果一致。 - 门控属性:
data-dsh-fit-nav/data-dsh-fit-composer/data-dsh-fit-mobile, 外加data-dsh-fit-navmode(三态)和data-dsh-fit-tight(实测窄行)。关开关就是摘属性, 规则随之失效。 - 变量统一:
--dsh-fit-ctl(控件直径,clamp(28px, 1.5vw + 20px, 36px))定义在样式表 第一行,导航图标和输入条按钮都读它。 - 不 import 任何
@deepseek-ai/*。primitives 只在模块表真的提供时才用,拿不到就走 朴素元素兜底。 - 颜色一律
--dsw-alias-*,不写死色值。 - 所有监听、观察器、槽位注册都在
apply内创建并返回清理函数。 - 四个槽位:
sidebar.footer.action两颗按钮(order 50 / 51)、sidebar.panellist.actions的「更多」菜单段(order 10)、settings.section的设置页(order 18)。 - 设置页自绘开关:不用 primitives 的
Switch(宿主禁止requireprimitives 包), 是button[role=switch][aria-checked],状态靠data-on给样式钩子。 - 模板字符串的注释里不能出现反引号——会截断模板,运行时
ReferenceError,而node --check查不出来(它只管语法)。
六、兼容性
| 端 | 合并前 | 合并后 |
|---|---|---|
| 桌面 | 导航生效;输入条部分生效;手机密度不生效 | 完全一致 |
| 手机 | 三者全生效 | 完全一致(默认全开) |
开关的存储方式:
| 项 | 存储 | 范围 | 默认 |
|---|---|---|---|
| 三个模块开关 | profile 的 cordis.patch.yml 对应行 config: |
账号级,多设备一致 | 全开 |
| 导航三态 | localStorage 的 dsh-ui-fit:nav |
设备级,每浏览器一份 | 标准 |
七、许可
Apache-2.0,见 LICENSE。
No comments yet. Be the first to write one.