dsh-myskin (v0.3.8)
DSH 通用皮肤框架:可视化自定义 + 实时预览 + 「皮肤管理」设置页,Web 与 Desktop 共用同一套客户端插件管线。
皮肤是一层完全可逆的覆盖层:不改 DSH 源码、不动 DSH 进程;关掉开关或点「还原默认」即回到原生外观。
适配 DSH 0.1.7-rc.2 与 0.2.0-rc.1(Web 与 Desktop)。
目录
这是什么
一句话:把 DSH 变成你自己的样子,而且随时能变回去。
- 不侵入:所有改动都写在插件自己的条目里(皮肤文档 + 一个自有
<style>),不碰 DSH 的源码、配置与进程。 - 可逆:每个字段都能逐项清除,「还原默认」或关掉「启用皮肤」即精确还原。
- 可视化:内置「绘制模式」画布编辑器——在真实页面上点选元素改样式、改文字、换字体、挪位置,边改边看。
- 可搬运:整套皮肤连同图片、字体打包成
.dshskin(类 zip 容器),换机器/换 profile 一键导入。
能做什么
皮肤管理页(设置 →「皮肤管理」)
| 能力 | 说明 |
|---|---|
| 启用 / 停用 | 一键开关整套皮肤;停用即完全还原 |
| 预设主题 | 深海 / 暖阳 / 极夜等一键换肤(走官方令牌通道) |
| 实时预览 | 不写入文档也能先看效果 |
| 绘制模式 | 在真实页面上可视化编辑(见下节) |
| 皮肤库 | 保存 / 重命名 / 上移下移 / 复制 / 加载 / 删除多个命名皮肤 |
| 导出 / 导入 | 皮肤包 .dshskin |
绘制模式(画布编辑器)
进入方式:设置 →「皮肤管理」→ 绘制模式。设置弹窗会关闭,真实页面内缩,顶部出现工具条、右侧出现面板——不是复制一份界面,就在真实页面上改。
选中元素
- 选择模式:悬停即显示虚线框与标签(
button#go.btn · 发送),点击选中;交互模式:正常使用页面(滚动、点按钮不会误选)。 - 面板顶部 ↑ 父级 / ↓ 子级(Alt+↑ / Alt+↓)按真实 DOM 一次走一级。
- 快捷键:
Esc取消选择(再按退出并保存)、Ctrl/Cmd+Z撤销、Ctrl/Cmd+Shift+Z重做——在输入框里不会抢键。
改样式(右侧面板,可折叠)
- 分组:文字 / 盒子 / 外观 / 位置与缩放 / 元素操作,标题带「自定义 N」计数。
- 每个已生效的字段都能单独清除(×),不用为改一个属性去清空整个元素。
- 字段改动即时预览;隐藏控件(保留占位)/ 移除控件(不占位)都是纯 CSS,不删除真实节点。
- 值一律走
--dsw-*令牌与真实 CSS,深浅色主题自动跟随。
位置与缩放
- X / Y 位移、等比缩放(带滑块);数值框上滚轮微调(X/Y ±1px、缩放 ±0.05,按住
Shift步长 ×5/×10)。 - 画布上选中框左上角 ✥ 拖动=双轴移动,右下角手柄拖动=等比缩放。
- 每个轴独立重置(↺),也可以一次「重置变换(三轴)」。
- 对齐线(低敏吸附):移动或缩放时,元素与同级/父级元素的边与中线、以及视口中线在 4px 内会自动吸附, 并在画布上画出对齐线;磁力很小(4px)且只在已经接近时生效,按住 Alt 可临时关闭,工具条「对齐」可整体开关。
- 只做视觉位移/缩放,不改变布局流;归零即删除
transform,不留transform: none。
文字与字体
- 「编辑文字」:自动定位真正承载文字的节点(含灰色的默认占位文字),边输入边预览,回车或「应用文字」写入草稿。
- 「字体」:可直接填任意字体栈(含系统字体),或用建议列表(PingFang SC / Microsoft YaHei / Noto Sans CJK SC / HarmonyOS Sans / JetBrains Mono …)。
- 嵌入字体文件:
.woff2/.woff/.ttf/.otf(≤ 30 MB)随皮肤保存;超过 2 MB 会明确提示代价(见下)。 - 应用到整页:把当前字体写到
body,整站生效(body无法在画布上点选,所以单给一个入口)。
画面
- 背景图(壁纸)+ 背景强度滑块(拖动即时预览、松手自动保存)。
- 嵌入图片:先选中一个容器,再选图;可拖动、缩放、调不透明度与混合模式。
- 令牌面板:按背景 / 边框 / 品牌色 / 文字 / 按钮 / 交互分组,逐项覆盖
--dsw-*。 - 工具条可收起右侧面板看整页;所有面板、工具条、选中框都是插件自有层,退出即消失。
保存 / 应用 / 关闭
| 按钮 | 行为 |
|---|---|
| 保存 | 写入皮肤文档并留在绘制模式继续编辑(不改变皮肤的启用状态) |
| 应用 | 写入 + 启用,并退出绘制模式 |
| ✕ 关闭 | 有未保存改动时先保存再退出;保存失败会保留编辑器并说明原因 |
皮肤包 .dshskin
「导出皮肤」产出的是一个标准 ZIP(任何解压工具都能打开),把"配置"和"素材"分开存:
| 条目 | 内容 |
|---|---|
manifest.json |
完整配置:令牌、CSS、文字替换、画布(背景/图片)、图层、皮肤库,以及格式版本、生成器、时间戳与资源清单(路径/类型/MIME/字节数) |
assets/… |
原样的图片与字体文件(不是 base64) |
README.txt |
包内说明 |
- 省体积:base64 变二进制文件。一份实测主题:351 KB 的 JSON → 141 KB 的皮肤包(−59.8%)。
- 可换素材:解开 zip,把
assets/里的图/字体换成同名同格式的文件,重新打包即可导入。 - 兼容:旧版
.json导出仍可导入;包内资源缺失或损坏会明确报错,不会导入半个皮肤。
安装(最新版 DSH)
给已经装好并能启动的 DSH 加一个第三方插件。本插件是 profile bundle(包内自带
cordis.patch.yml,声明条目dsh-myskin),所以只需要"装进某个 profile + 在它的dsh.profile.bundles里声明一次"。
方式一:用 DSH 内置的「添加插件」(推荐)
打开 设置 → 插件(Plugins)→ 添加插件,在输入框里填下面任意一种,选好安装源,点「安装」:
| 输入 | 例子 | 说明 |
|---|---|---|
| GitHub 仓库地址 | https://github.com/WTStarMark/dsh-myskin |
走 git 安装;也可写 github:WTStarMark/dsh-myskin,需要固定版本就加 #v0.3.8 |
| npm 包名 | dsh-myskin |
走所选安装源(registry.npmmirror.com = 中国大陆镜像源) |
| 本地目录路径 | ~/dsh-plugins/dsh-myskin-0.3.8 |
等价于 link:,改源码即时生效 |
- 「安装源」只影响 npm 包;填 GitHub 地址时走 git,不受它影响。
- 安装由 pnpm 执行,机器上需要有
pnpm。 - 安装完成后,插件管理器会自动把
dsh-myskin写进当前 profile 的dsh.profile.bundles——不需要手改配置文件。 - 请注意界面上的提醒:插件暂不支持自动更新;升级请先在插件页卸载,再安装新版本。
- 只想给桌面端装,就在桌面版里对同一个地址再装一次(Web 与 Desktop 是两个 profile,皮肤文档也各自独立)。
方式二:离线 / 手动安装(用打包好的 zip)
解压插件包
dsh-myskin-0.3.8.zip:# 有 unzip 就用它;没有就用 python3(zip 是标准格式) python3 -c "import zipfile; zipfile.ZipFile('dsh-myskin-0.3.8.zip').extractall('$HOME/dsh-plugins')"放进目标 profile(目录名必须是
dsh-myskin):DSH_HOME="${DSH_HOME:-$HOME/.dsh}" PROFILE="$DSH_HOME/profiles/web" # 桌面版改成 profiles/desktop mkdir -p "$PROFILE/node_modules" cp -r ~/dsh-plugins/dsh-myskin-0.3.8 "$PROFILE/node_modules/dsh-myskin" # 或软链(改包即时生效):ln -sfn ~/dsh-plugins/dsh-myskin-0.3.8 "$PROFILE/node_modules/dsh-myskin"在
$PROFILE/package.json的dsh.profile.bundles末尾追加"dsh-myskin"(不要删掉原有条目):{ "dsh": { "profile": { "bundles": ["@deepseek-ai/dsh-base", "@deepseek-ai/dsh-web-app", "dsh-myskin"], "patchReload": "live" } } }生效:
patchReload: live时保存后刷新页面即可;没反应就重启 DSH(由你操作,本插件从不重启 DSH)。
装上了吗
设置里出现 「皮肤管理」 → 成功。
只用命令行确认宿主半区(把
<pkg>换成实际安装目录):node --input-type=module -e "const m = await import('<pkg>/lib/index.js'); console.log(Object.keys(m))" # 期望输出:[ 'Config', 'apply', 'name' ]
卸载 / 回滚
- 用界面装的:插件页对该插件选「卸载」(它同时会从
dsh.profile.bundles移除)。 - 手动装的:从
dsh.profile.bundles移除"dsh-myskin",删掉$PROFILE/node_modules/dsh-myskin(或解除软链),刷新页面或重启 DSH。 - 皮肤文档仍留在该 profile 的
cordis.patch.yml里;想彻底清干净,先「导出皮肤」备份,再删掉该条目。
快速上手
- 设置 →「皮肤管理」:选一个预设主题 → 点 应用。
- 点 绘制模式:在真实页面上点选一个元素,右侧改颜色/字号,或直接在「编辑文字」里改文案(边打边变)。
- 保存(继续调)或 应用(写入并退出绘制模式)。
- 导出皮肤:得到
.dshskin备份,换机器或换 profile 时 导入皮肤 即可。
数据与持久化
- 皮肤文档保存在该 profile 的
cordis.patch.yml(插件条目dsh-myskin的config)。 - 由于文档跟着 profile 走,Web 与 Desktop 的皮肤互不共享——用
.dshskin导出/导入搬运。 - 「皮肤库」可以存多套命名皮肤,随时切换。
- 关掉「启用皮肤」= 页面完全还原(文档仍保留,随时再打开)。
常见问题
Q:启动时报 dsh-myskin (dsh-myskin): failed to import?
这句由 DSH 的启动器在"Loader 没拿到 fiber"时记下,真实异常被吞掉了。按顺序排查:
- 目录名/位置对不对:必须是
$PROFILE/node_modules/dsh-myskin,里面能看到lib/index.js与cordis.patch.yml; - 宿主半区能否独立导入:
node --input-type=module -e "await import('<pkg>/lib/index.js')"—— 能打印Config,apply,name就没问题(本包的lib/index.js自带依赖,解压/拷贝/软链三种装法都不需要node_modules); - 该 profile 的
dsh.profile.bundles里是否真的写了dsh-myskin; - 还不行就重启 DSH(
patchReload: live才热更)。
Q:点「应用」提示保存失败?
多半是文档太大。壁纸/嵌入图会按最长边自动压缩,但嵌入字体是原样保存的:超过 2 MB 就会让每次保存都变慢,太大可能直接被拒绝。建议整站字体用系统字体名,或使用子集化后的 .woff2。
Q:改了没效果? 确认「启用皮肤」是打开的;再看当前是哪个 profile(Web 里改的不会出现在 Desktop);用「实时预览」先确认改动本身有效。
Q:绘制模式里设置弹窗位置怪怪的? 这是有意的:绘制模式下真实页面会内缩,设置弹窗遵守同一条内缩规则,所以它落在应用区里居中,而不是被工具条/面板盖住。
Q:怎么把皮肤带回原生? 「皮肤管理 → 还原默认」清空整套皮肤;或关掉「启用皮肤」。两者都不影响 DSH 自身。
兼容性
| 项目 | 状态 |
|---|---|
DSH 0.1.7-rc.2 |
已适配 |
DSH 0.2.0-rc.1 |
已适配 |
| 平台 | DSH Web 与 DSH Desktop(Windows / macOS / Linux 上的桌面壳同理) |
DSH < 0.1.7 |
不支持(0.1.7 起才有本包使用的 Config + profile bundle 形态) |
许可
MIT © WTStarMark · 仓库:https://github.com/WTStarMark/dsh-myskin
No comments yet. Be the first to write one.