dsh-background-by-model
Per-model appearance for the DSH Web UI: an ordered rule list matched against the current session model name, each rule carrying its own wallpaper, theme colour, layout mode, framing and wallpaper opacity and blur, plus per-surface opacity and frosted-glass blur for the main background, left panel,
Install
dsh plugin --profile web add dsh-background-by-model
Sandbox test results
| Stage | Result |
|---|---|
| 1 install | ✓ |
| 2 list | ✓ |
| 3 mount | ✓ |
| 4 boot | — |
Four stages run in an isolated sandbox: install (network on) → list → mount → boot (last three with no network).
README
dsh-background-by-model
<p align="center">
<a href="https://github.com/HarmlessFunny/dsh-background-by-model"><img src="https://img.shields.io/github/stars/HarmlessFunny/dsh-background-by-model?style=social" alt="GitHub stars"></a>
<a href="https://www.npmjs.com/package/dsh-background-by-model"><img src="https://img.shields.io/npm/v/dsh-background-by-model" alt="npm version"></a>
</p>
[English](README.md) | 中文
派生自Tkingxiao/dsh-any-background,并重命名为dsh-background-by-model。
一个 DeepSeek Harness 外观插件,核心是一份有序的模型规则列表:每条规则自带壁纸(可多张),每张图各有自己的布局模式、取景、主题色,以及透明度、亮度与模糊度。切换模型即切换背景,切换过程走你在「配置」页选定的全局[切换效果](#切换效果全局)。
v0.3.0 是破坏性更新 —— 视频背景、生成式背景与全局主题色均已被移除。详见 [CHANGELOG.zh.md 的 v0.3.0 条目](./CHANGELOG.zh.md#v030)。
模型规则如何工作
一条规则 = 一个匹配串 + 一整套背景外观。切换模型时,插件读取当前会话的模型名,自上而下扫描列表,使用第一条「匹配串出现在模型名里」的规则(忽略大小写)—— 都没命中时用第 1 条兜底。
示例列表:
# · 匹配串 · 背景图
1 · deepseek · 图 1
2 · flash · 图 2
3 · glm · 图 3
当前模型 · 结果 · 原因
DeepSeek-Flash · 规则 1 → 图 1 · deepseek 先命中
GLM-Flash · 规则 2 → 图 2 · flash 比 glm 更靠前
Qwen-Flash · 规则 2 → 图 2 · flash 命中
GLM-Turbo · 规则 3 → 图 3 · 只有 glm 命中
Kimi-K3 · 兜底 → 规则 1 → 图 1 · 都没有命中
- 顺序即优先级 —— 先命中者胜,而不是最精确者胜;需要时拖动规则调整顺序。
- 匹配串留空表示该规则不参与匹配、只作兜底,所以「单规则 + 空匹配串」就是一张图到处用。
- 匹配串会同时比对 provider、模型 id 与模型显示名拼接出的字符串,三者任一都能用来选中规则。
- 当前模型取自本会话的持久化模型选择(输入框上模型选择器读的同一个
modelSelection投影),所以会话内切换模型会立即生效;页面会显示读到的是哪个模型,只读到宿主全局默认时额外标注宿主默认。
上面的示例表里没有kimi,所以切到 Kimi 会走到兜底 = 规则 1 = 图 1,看起来像「没反应」—— 想给 Kimi 单独配图就加一条匹配串为kimi的规则。
截图
同一套界面、同一份配置,只因为当前模型不同:
<p align="center">
<img src="https://cdn.jsdelivr.net/gh/HarmlessFunny/assets@v0.1.0/dsh-background-by-model/wallpaper-deepseek.webp" alt="DeepSeek 下的外观" width="880">
<br/>
<em>DeepSeek V4.1 Flash · 命中匹配串含 <code>deepseek</code> 的规则:浅色壁纸 + 与图相配的主题色</em>
</p>
<p align="center">
<img src="https://cdn.jsdelivr.net/gh/HarmlessFunny/assets@v0.1.0/dsh-background-by-model/wallpaper-kimi.webp" alt="Kimi 下的外观" width="880">
<br/>
<em>Kimi K2.7 Code · 命中匹配串含 <code>kimi</code> 的规则:深色壁纸 + 深色主题,整个界面跟着换肤</em>
</p>
<p align="center">
<img src="https://cdn.jsdelivr.net/gh/HarmlessFunny/assets@v0.1.0/dsh-background-by-model/rule-editor.webp" alt="单条规则的编辑器" width="660">
<br/>
<em>「模型背景」页的单条规则 · 布局模式、取景、主题色与透明度/亮度/模糊,全都属于它正在编辑的那张图</em>
</p>
<p align="center">
<sub>示例壁纸素材来源于 bilibili <a href="https://space.bilibili.com/4168597">ZipZipPipe</a></sub>
</p>
功能特性
模型规则
一份有序的规则列表,按当前模型名先命中者胜,第 1 条兼任兜底。
- 规则 —— 增删、排序、命名;每条自带一个匹配串,以及一组图片与它们各自的外观。
- 每条规则多张图 —— 胶片条可用文件选择、拖放或一行一个网址填入;可排序、设为第一张、或原地替换(替换会保住它在轮换里的位置)。规则也可以一张图都没有,而只要它还有自己的主题色,空规则依旧参与匹配,所以「清空」是一个看得见的状态,而不是一个陷阱。
- 实时匹配状态 —— 「模型背景」页会显示读到的是哪个模型、落在哪条规则上。
- 导入 / 导出 —— 整套规则导出为
dsh-background-by-model-theme.json,图片全部内联;旧版本写出的文件仍可导入。 - 存在磁盘上,不在
localStorage—— 一切都在~/.dsh/.dsh-background-by-model-data/下,旧的单图配置在第一次读取时就地迁移。 - 中英双语,自动识别语言环境;宿主重置主题时由守护逻辑重新施加。
多图轮换
按规则开启,默认关闭 —— 轮换真的要花流量、内存和电,所以没有东西会替你打开它。
- 停留时长 —— 10 秒 / 30 秒 / 1 分钟 / 5 分钟 / 30 分钟,或任意自定义秒数(5 秒 – 24 小时)。
- 顺序 —— 按顺序走完列表后环绕;随机在除当前这张之外的所有图片中等概率挑选,所以不会出现「像没触发」的一跳。
- 切换模型时也换一张 —— 第二种触发,完全不排定时器。
- 下一张 —— 随时手动换图,与定时器在不在跑无关。
- 只有生效的那条规则在轮换,全插件只有一个定时器;标签页隐藏时轮换跟着画面一起停。
切换效果(全局)
壁纸切换时的样子 —— 「配置」页上的一个设置,所有规则共用,覆盖切模型、轮换一步、手动下一张与节日接管。
- 四种效果 —— 淡入淡出(默认)、直接切换、缩放淡入、平移推入;后两种只对进来的那一层做
transform,所以一个字节的额外传输都不花。 - 缓动与同一个时长 —— 标准 / 线性 / ease-out / ease-in-out,以及
0–3000 ms,其中0是硬切而不是「没设置」。它取代了rotate.fadeMs这个没有任何控件能到达的逐规则字段,手调过的值会在第一次读取时折算进来。 - 「减少动态效果」是否决,而不是把动画缩短。
- 界面配色和壁纸走同一个时钟 —— 只有浅↔深互切立即切换,因为两套调色板之间插值会走过两个方向都读不清的中间调。
- 预览色块会重放这个效果,因为壁纸淡入它自己是什么都看不见的。
节日特殊背景
「配置」页上一个开关,别的什么都没有:中秋与国庆当天壁纸换成该节日自己的画与固定主题色,第二天早上换回来。它出厂是关的,[推荐配置](#推荐配置)会替你打开。
- 中秋是农历八月十五,按北京时间从中国农历解析,所以每年都动(2024-09-17、2025-10-06、2026-09-25 …);国庆是 10 月 1–7 日;两者撞上时中秋优先。
- 没有图的节日会顺延给模型规则,而不是把背景刷白。
- 画是下载的,不随包发布 —— 每个节日一张压缩后的壁纸,从B 站图床(
i0/i1/i2.hdslb.com,三个边缘互为回落)取,当天第一次读取时缓存到holiday-cache/<哈希>/。缓存目录名来自 URL 里那段内容哈希:换图就必须换地址,于是换目录、必然重下,没有需要记得去改的版本号。下载由日历把关,所以平常的日子一个字节都不取,此后的每一次启动都直接读盘。 - 画和它的配色都不可以换 —— 节日槽位只读,颜色与满幅的「填充」都取自定义,主题导出也只带你的规则。
每条规则与每张图各自的设置
- 壁纸 —— 每条规则一张或多张图;不轮换时规则画的是第一张。
- 主题色 —— HSL 色轮、数值输入、从本图提取与吸管。它属于图片,没有自己颜色的图跟随系统主题,而不是继承规则色。
- 布局模式 —— 适应 / 填充 / 拉伸 / 平铺 / 居中,逐图保存;规则没有图片时这排是禁用而不是隐藏。
- 取景 —— 拖动平移、滚轮缩放,只在适应模式下可编辑,逐图保存,窗口缩放后保持一致。
- 图片透明度
0–100%、图片亮度0–200%(100%即原图)与图片模糊0–60 px,三者都逐图保存,并通过同一条滑块 + 旁边的下拉框切换调节项 —— 一张亮图和一张夜景图因此在同一组轮换里各有各的曝光。它们只作用于图片层;「界面」页的透明度作用于界面各区域。没有任何图片的规则这三项是禁用而不是隐藏。
全局设置(「界面」页)
- 每个界面部件各自的透明度 —— 主背景、左侧栏、右侧栏、卡片与菜单、输入框与控件、设置面板、对话文本框、轨迹页与每一个插件页,各有一条滑块。
- 新装出来就已经是作者本人那套外观,所以第一次运行不需要下载任何东西。
- 与主题色无关 —— 规则没有主题色时,这些滑块全部照常可用。
推荐配置
「配置」页点一下就换上作者本人的整套配置 —— 七条模型规则与那套界面数值随插件内置,只有七张壁纸从B 站图床下载。
- 规则不再是远端文件 —— 它编译在包里,和读它的代码同一个版本。所以这个按钮不需要 GitHub 能通,也不存在「远端配置比插件新」这种要拦的情况:能被安装的规则,永远是这份构建自己写的那些。
- 壁纸地址是一张常量表 —— 槽位 → BFS 路径,编译期就定死了。请求清单因此不是从网上下载来的,一次按错也不可能变成「按别人的清单去取 64 个文件」。
- 一个地址对应一份内容 —— BFS 的路径是上传内容的哈希,所以壁纸地址天然不可变,不像 git tag 那样能被重新指向别的字节。
@3840w.webp是必须的 —— 它们上传的原图是 2.4–12 MB 的 PNG(九张合计 76 MB),加上这个后缀才是 250–365 KB 的 4K WebP,也正是现有数据目录里已经存着的那份字节(sha1 一致)。- 里面每一个界面数字都是插件本来就用着的值,所以在新装上是「加上规则和图片」;而在你已经调过的数据目录上,它把这些也一起重置 —— 它是一整份配置,不是一个补丁。
- 先下载、后提问,所以确认框能如实说出手里有什么 —— 而清空在下载之后,绝不在之前。它是面板里唯一一张会先问再删的卡片。
- 少一张壁纸就整体失败并报出是哪个槽位,而且每个文件各自重试(三个边缘 × 三轮),已经下到的部分留给下一次。
图片存储清理
「配置」页最后一张卡片:图片是按原图保存的,所以一次被中断的上传、一次失败的文件删除,或一次整套配置的替换,都可能在磁盘上留下不再被任何规则引用的文件 —— 而这台机器上「孤儿」正常是 0。卡片把用量读出来,点清理就直接删。
- 先读、后删 —— 卡片先显示「可清理多少 MB / 几个文件」,再给出清理按钮;先删再报数的操作没人会同意。数字只描述这一按会释放什么:显示「正在使用 2.1 MB」是在回答一个没人问的问题,而显示「8 个文件」会让人以为八张全要删掉。
- 只删没人引用的 —— 当前规则用到的图一个字节都不动,配置本身也不写。清理完会重新读一次,而不是用减法算,所以删除失败的文件仍然算在里面。
- 失败会点名 —— 一个文件删不掉不会让其余六个留下来,但也不会被说成「已清理」:提示
…(truncated)
Rendered from the README published on npm. Formatted only, not edited.
Versions
Published on npm::36,最后更新 2026-11-01