dsh-theme-studio
Manifest valid★ 1DSH 主题工坊 — 可自定义背景色/背景图、字体、输入框、边栏颜色的 DeepSeek Harness 主题插件(实时生效,43 项测试)
dsh-theme-studio · DSH 主题工坊
A theme plugin for DeepSeek Harness Web / desktop clients: custom background (colour, opacity, wallpaper, sidebar image), text, composer and sidebar colours, with a live settings page in Settings → Theme Studio. No restart, no DOM hacks — the colours are stacked through
ctx.theme.overrideTokens, plus a guarded!importantlayer for surfaces that an installed skin repaints itself. Package shape is a standard DSH bundle, sodsh plugin --profile <profile> add <this repo>is enough. Test suite included (pnpm test, 43 checks).
给 DSH Web / 桌面客户端用的「自定义配色」插件。装好之后在 设置 → 主题工坊 里就能改:
| 项目 | 说明 |
|---|---|
| 背景色 + 背景透明度 | 整个会话区的底色,不透明度可调(0% 全透明 → 100% 不透明) |
| 字体颜色 | 主文本色 + 次要文本色(说明、时间戳、占位提示) |
| 输入框颜色 | 底部输入卡片的底色,同样带不透明度 |
| 边栏颜色 | 左侧会话列表栏的底色,同样带不透明度 |
| 边栏背景图 | 给边栏单独放一张图(和主背景图互不影响):本地图片或 URL、填充方式、3×3 位置、暗化;图片留白处露出边栏底色 |
| 背景图 | 本地图片或图片 URL;可调填充方式(智能 / 铺满 / 完整 / 原始大小 / 平铺 / 拉伸)、显示位置(3×3 锚点)、暗化程度或按图片亮度自动暗化;每张图分别记住自己的填充/位置 |
所有改动 即时生效,不需要重启;配色保存在浏览器 localStorage,可导出 / 导入 JSON 备份。
安装
方式 A:交给 DSH 自己装(推荐)
从 GitHub 直接装:
dsh plugin --profile <profile> add https://github.com/baizz-520/dsh-theme-studio
或者从本地目录装:
dsh plugin --profile <profile> add <本目录绝对路径>
也可以在 DSH 的 Plugins / 插件市场 页面里安装,或手动把本目录放到 profile 的 node_modules 下(见方式 B)。
方式 B:手动放进去
- 把本目录复制(或建软/硬链接)到
<DSH_HOME>/profiles/<profile>/node_modules/dsh-theme-studio; - 在
<DSH_HOME>/profiles/<profile>/cordis.patch.yml末尾追加:
- insert:
- id: dsh-theme-studio
name: dsh-theme-studio
- 重启 DSH(或让 HMR 重新计算配置)。
<DSH_HOME> 默认是 %USERPROFILE%\.dsh,桌面端的 profile 名一般是 desktop。
使用
- 打开 设置(左下角齿轮)→ 左侧导航选 主题工坊;
- 顶部的 启用主题 是总开关;
- 每张卡片右上角的开关表示「是否覆盖内置配色」,关掉就沿用 DSH 自带配色;
- 想快速换个风格,先点一个 预设,再逐项微调;
- 用 背景图 时记住:启用/选图会自动把「背景」的不透明度降到 78%,图片才有地方透出来;想要更清楚就把不透明度再往下调。
- 填充方式决定图片怎么放进这块区域:
智能(默认)= 图片比例和窗口接近就铺满、差太多就完整显示,避免竖图被横窗裁掉大半;铺满= 等比放大裁掉多余;完整= 整张图都看见、四周留底色;原始大小= 按图片像素显示(小于区域就按锚点摆放);平铺= 按原始尺寸重复铺开(适合小图案/纹理);拉伸= 强行拉满会变形。 - 显示位置是 3×3 锚点(左上 … 右下):
铺满时决定裁切保留哪一块,原始大小/完整时决定图片贴在哪一边,平铺时决定重复的起点。 - 自动暗化打开后,插件会把图片缩到 16×16 取样、算平均相对亮度,越亮压得越暗(0–45%),并把结果显示在开关下面;图片本身暗就几乎不压。跨域且没有 CORS 头的图读不到像素,这时会自动回退到手动暗化并在页面上说明。
- 每张图单独记忆:换图时如果这张图以前调过填充/位置,会自动恢复;最多记 20 张(按图片内容哈希存,不存图本身)。
- 边栏背景图是独立的一张图:画在
[data-slot="sidebar"]的列容器上,垫在边栏底色之上(所以「完整」留白处露出的是你设的边栏色,不是主背景)。它不受主背景图的开关影响,两者可以同时启用。
「跟随 / 自定义」与透明度的关系
- 每项默认「自定义」关闭(即沿用内置配色),所以刚装好时界面不会变化 —— 动一下任意颜色或点预设即可。
- 背景不透明度为 100% 时,背景图基本看不到;想让背景图(或窗口后面的内容)透出来,就调低这一项。
- 边栏 / 输入框的不透明度低于 100% 时,会透出「背景」那一层(即背景色或背景图)。
和皮肤(Skins)的关系
- 装了立绘类皮肤(如 maid-atelier)时,插件在启用背景图期间会隐藏皮肤自己那条整屏立绘(统一的
[data-skin-chrome]约定),否则它会把你的图整块盖住;皮肤的版式、字体、其它装饰都保留。 - 皮肤给「列 / 面板」写死的底色,令牌和继承都碰不到(自己的声明永远赢),所以插件会在运行时找出真正不透明的那些表面,就地画上背景图。对话框、菜单、弹层不参与,保持自己的底色。
实现说明(给想改代码的人)
- 浏览器端是一个
window.__ModuleLoader__.load({ id, factory })形式的 CJS 形态 bundle(lib/client.js),宿主端lib/index.js是空实现 —— 该功能没有任何 Host 侧行为。 - 颜色走两条并行通道,缺一不可:
ctx.theme.overrideTokens('dsh-theme-studio', tokens)叠一层令牌覆盖层(不改内置主题、卸载即移除);- 一组带
!important的"直接绘制"规则,用html[data-dts-*]属性门控 —— 因为皮肤在自己作用域上重新声明同名令牌时,继承来的值永远赢不了,只靠令牌会出现"改了一半"。
- 覆盖的令牌:
| 控件 | CSS 令牌 |
|---|---|
| 背景 | --dsw-alias-bg-base |
| 边栏 | --dsw-specific-sidebar-fill |
| 输入框 | --dsw-specific-input-major |
| 主文本 / 次要文本 | --dsw-alias-label-primary / --dsw-alias-label-secondary,并由次要色派生 -tertiary / -caption / -dimmed / -primary-dimmed |
- 背景图不是一个独立图层:它按需画在"运行时发现的、真正盖住视口的那些不透明表面"上(
background-attachment: fixed保证多层严格对齐成一张图)。独立图层方案在装了皮肤时不成立 —— 画布层会被壳的wFrame和列底色挡住,::before + z-index:-1会被所有不透明内容挡住,z-index抬高又会盖住整个界面。 - 背景图的图层字符串在 JS 里拼好后以内联
!important写入,不用var()代入url(...):多图层background-image里只要有一层解析失败,整条声明作废,图片会静默消失而底色还在。 - 设置页通过
ctx.slots.register({ name: 'settings.section', ... })注册,文案走ctx.locale.register('settings.theme-studio', { zh, en })。
测试
包内自带一套行为测试,直接跑真实 bundle(不是 mock 实现):
node test/client-harness.mjs # 或 pnpm test
它搭一个够用的 DOM 桩(含 window.getComputedStyle、MutationObserver、Image、canvas、localStorage、URL.createObjectURL、FileReader),把设置页真正渲染出来、逐个点过每一个控件,然后断言:
- 令牌层叠/替换/释放次数与内容(含
-tertiary/-caption/-dimmed派生色); - 四条"直接绘制"属性、根变量、颜色/不透明度的
rgba()换算; - 背景图 6 种填充 →
background-size/background-repeat映射、3×3 锚点、暗化梯度、URL 转义; - 每图独立记忆的往返(A → B → A);
- 边栏背景图只落在边栏列、不串到主区;
- 超大文件被拒、坏 JSON 被拒且不改动已有配置、有效导入被应用、恢复默认;
- 总开关关闭后令牌层被释放、所有内联绘制被清掉;
- 卸载后再
apply()(HMR 反复启停)能恢复; - 卸载后延迟回调不再重绘;
- 每条文案键在 zh/en 都存在;
- 全程
console.error为零。
当前基线:43/43 通过。
兼容性
- 需要客户端提供
slots/locale/theme三个服务,以及theme.overrideTokens(DSH 0.2.0 起具备)。 - 只在
platform: web的客户端加载;不涉及模型、工具、网络请求。
卸载
在插件页停用,或删掉 cordis.patch.yml 里那三行 insert,然后 dsh plugin --profile <profile> remove dsh-theme-studio。
License
MIT
Comments
Loading…
From the same category
by awesome-dsh-plugin
A curated list of plugins for DeepSeek Harness (dsh) · DeepSeek Harness 插件精选列表
★ 19.2k
CC0-1.0
Python
Oct 17, 2026
by 0xsline
DeepSeek Harness (DSH) ecosystem: curated plugins, tools, and infrastructure from dsh-external/hub and the public dsh-plugin topic.
★ 1.2k
CC0-1.0
Python
Oct 16, 2026
by pax-beehive
Open-source CLI, schemas, resolver, and DSH agent tools for DSH Plugin Hub
★ 391
MIT
TypeScript
Oct 6, 2026
by xiajiajun516
DeepSeek Harness (DSH) backup & restore plugin — export, import, migrate and sync your complete DSH configuration, plugins, MCP servers, skills and workspace. One-click migration to another machine.
★ 201
MIT
TypeScript
Oct 17, 2026
dsh plugin --profile web add dsh-config-managerby yjh051108
推荐组件(非必须):DeepSeek Harness 运行时注入器;已随 dsh-routing-suite 单仓库化保留,本仓库继续维护/发布。
★ 167
TypeScript
Oct 16, 2026
dsh plugin --profile web add @dsh-external/dsh-super-injectorby jigjoy-ai
A CLI that turns a goal into a pull request - and a sandbox for testing concurrent AI coding agents on the Mozaik runtime.
★ 124
MIT
TypeScript
Oct 13, 2026