dsh-web
zhu1090093659/dsh-webDeepSeek Harness(DSH)Web 插件聚合生态包 · 一切皆插件,创意工坊分发(dsh-market.com)
DeepSeek Harness 桌面版主题皮肤画廊插件 —— 一个插件管全部皮肤(JSON 数据驱动,内置 山青婷彩 / 梦海游鱼),npm/tarball 安装零构建授权 | A community theme gallery plugin for DeepSeek Harness: JSON-defined skins with full-screen coverage
给 DeepSeek Harness 的主题画廊:一个插件 + 一堆 JSON 皮肤。装一次,拿到全部主题;加皮肤不用改代码、不用重启、不用重新装包。
| 你想要 | 怎么做 |
|---|---|
| 直接用别人做好的皮肤 | 装上插件,在设置里点选 |
| 自己做皮肤(或让 AI 做) | 在 lib/themes/ 加 JSON 后重跑 npm run embed-themes,或装 dsh-theme-skin-author 技能让 AI 生成 |
| 贡献一个皮肤给所有人 | 在 lib/themes/ 放一个 JSON,提 PR |
已随 0.8.3 发布 12 套皮肤:六套复刻自蜂链商城电商新零售系统管理后台
(renjie2026/fenglianshop-open 的
admin-modular/src/utils/themes.js),两套是本插件原创的宠物主题(同一套造色方法,色相取自中国传统色库),
一套是**「纯色/拼色」配色选择器卡片(15 个可点色值,见下),
还有三套深色主题**——大鲸鱼娘(社区同人立绘 · 深海夜航,见 出处与致谢)与
**青玉凤剑 / 青玉凤剑(带壁纸)**两套全屏武器主题(原创,同一套双剑素材 + 气焰特效的两个独立主题位,后者带国风背景壁纸)。
| id | 名称 | 主色 | 强调色 |
|---|---|---|---|
shan-qing-ting-cai | 山青婷彩 | #2F7D5E 青山绿 | #E88BB0 蜻蜓粉 |
meng-hai-you-yu | 梦海游鱼 | #177CB0 靛青 | #FFD166 琥珀金 |
jiang-pan-dong-yun | 江畔冬云 | #3A556B 冬云青灰(按钮/边框族) | #F2C879 冬云暖金 |
ying-mu-cai-yun | 营慕彩云 | #2D5A3D 林间深绿 | #FFB347 琥珀 |
pei-an-jie-xin | 佩安杰心 | #7A5C3E 暖檀褐 | #B4653A 赭陶 |
xu-shan-jun-yue | 徐山军月(复刻) | #2C3B2E 夜山松绿(按钮/边框族) | #D4B266 军月金 |
hu-po-mao-mi | 琥珀猫咪(原创) | #9C5F24 琥珀深焙(按钮/边框族) | #CA6924 琥珀(中国传统色) |
hu-zi-a-huang | 虎子阿黄(原创) | #896C39 秋色(按钮/边框族) | #F0C239 缃色(中国传统色) |
shi-liu-jin | 纯色/拼色(配色选择器) | #F20C00 石榴红(默认那套「石榴金」) | #9D2933 胭脂(按钮族) |
da-jing-yu-niang | 大鲸鱼娘(社区同人立绘) | #061320 深海夜蓝(半透明壁纸底) | #5FD9F5 鲸鳍水青 |
longyan-baojian | 青玉凤剑(原创·全屏武器) | #0E1822 深夜青碧(半透明渐变底) | #E8C25A 金凤金 |
longyan-baojian-2 | 青玉凤剑(带壁纸)(原创·全屏武器) | #0E1822 深夜青碧(国风壁纸衬底) | #E8C25A 金凤金 |
面板里另有两张内置外观卡(浅色 / 深色)、一张宠物挂件卡(宠物挂件 · 七只小伙伴)、
一张心情问候卡(心情问候)和一张菜单折叠卡(菜单折叠):它们都不是皮肤,
所以不计入上面这 12 套。
内置卡把配色切回官方的浅色 / 深色(与「设置 → 通用 → 外观」同一套),我们在官方浅色/深色上加了一点小惊喜
—— 见 效果预览 最后一行。官方外观里的「跟随系统」不出卡:它就是浅色/深色二选一,
再占一张卡只是重复。宠物挂件卡则完全不碰主题:点头像换宠物、点卡身开关挂件,
与任何皮肤都能同时开启(见 宠物挂件)。
心情问候卡同样不碰主题:它控制标题栏上一条滚动的问候语,默认开启、35 分钟换一条,
可调速度 / 方向 / 位置区域(见 心情问候语)。
菜单折叠卡也不碰主题:开启后侧栏不再显示入口,设置页里留一个轻量一键入口
(打开面板 / 恢复侧栏),默认关闭(见 菜单折叠)。
工作区里另有四套皮肤仍在打磨,尚未发布:光彩凤晨 guang-cai-feng-chen(复刻);
取意古风歌曲《白羽行》的两套原创——流星白羽 liu-xing-bai-yu、姑苏繁花 gu-su-fan-hua;
以及青冥飞剑 qing-ming-fei-jian(原创,全屏三剑编队入场 + 悬停自旋 + 聊天区宝剑壁纸,已实机验收)。
⚠️ 深色皮肤有 大鲸鱼娘 与 青玉凤剑 两套(2026-10-01 起青玉凤剑同为 colorScheme dark、 102 token 深色形态):外壳里「规划卡片 / 交付物 / 变更 / JSON 树 / 思考区」几处用的是 只在外观偏好为深色时才切深色底的组件级常量(
--plan-card-fill=--dsw-static-neutral-50#f9fafb, 声明在卡片元素自身,皮肤令牌层盖不到)。把「设置 → 通用 → 外观」设为深色,这些面板才是深色卡片 (实测:浅色偏好下正文压在那张 #f9fafb 卡片上只有 1.08:1;深色偏好下走 #2c2c2e → 12.37:1)。 🐋 大鲸鱼娘的入场特效:选中这套皮肤时,她会从窗口右上角的画面之外俯冲进来、 向左下横扫过整个工作区,再在主区绕一个完整的大圈(经过收口处的闭合环), 最后落到她那个站位上(约 1.8 秒,落点带一点过冲再回弹; 身后拖一串水泡、落地时一圈很淡的水花), 停在最前方——正文之上——约 1.2 秒(她完全清晰);约 3 秒时交叉淡入淡出(约 0.45 秒) 转成背景壁纸:立绘搬到body级、独立层上,一张伴生样式表(与壁纸层同生共死) 把应用表面变成半透明,于是正文压在她上面(左侧压暗、右下留亮)。 ⚠️ 这一层用层序而不是负 z-index 实现(2026-09-30 实测修正):壁纸层z-index:0、 应用内容#root抬到1、装饰层维持60—— 负 z-index 会被压在画布底色之下, 实机现象就是"3 秒后完全看不见她"(且没有任何异常)。 切到别的皮肤再切回来会整套重播;系统开启「减少动效」时跳过飞入与交叉、直接呈现壁纸态 (不等待,人物照常显示);config: { ambient: false }急停时立绘层、伴生样式表与标记类一起撤掉。 (发布前自检会核对这份清单:README 里的每个 id 都要真实存在,lib/themes里的每套皮肤也必须在这里被提到。)
每个皮肤 67 个 token,覆盖整屏。
青玉凤剑 longyan-baojian(原创) | 青玉凤剑(带壁纸) longyan-baojian-2(原创) |
|---|---|
![]() | ![]() |
大鲸鱼娘 da-jing-yu-niang(社区同人立绘) |
|---|
![]() |
山青婷彩 shan-qing-ting-cai | 梦海游鱼 meng-hai-you-yu |
|---|---|
![]() | ![]() |
营慕彩云 ying-mu-cai-yun | 佩安杰心 pei-an-jie-xin |
|---|---|
![]() | ![]() |
琥珀猫咪 hu-po-mao-mi(原创) | 虎子阿黄 hu-zi-a-huang(原创) |
|---|---|
![]() | ![]() |
江畔冬云
jiang-pan-dong-yun(0.7.0 新增)的实机截图下次更新补上:冬云低垂、江畔泛舟, 侧栏是灰蓝江天与层叠冬云。它自 0.7.0 起已在包里,装最新版即可直接用。
内置浅色 / 深色 + 皮肤素材 —— 那个小惊喜
| 内置「浅色」+ 山青婷彩的侧栏素材 | 内置「深色」+ 营慕彩云的侧栏素材 |
|---|---|
![]() | ![]() |
「纯色/拼色」卡片 —— 同一张卡、两套配色(点色格即时换色;卡片名旁边的「已应用」标出当前那套)
| 石榴金配色(默认) | 换点「松柏绿」那一格之后 |
|---|---|
![]() | ![]() |
玩法:先点一套皮肤,再点「浅色」或「深色」 —— 调色回到官方外观,而侧栏素材留在原处 (切到另一套皮肤时素材会正常替换;重启应用后不会有残留,因为那时的页面上本来就没有"上一套"可留)。
截图取自桌面版 0.1.7-rc.2 实机。图片用绝对地址引用而不是相对路径,是为了让同一份 README 在
GitHub、npm 与社区市场三处都能显示(npm 不会把相对路径解析到仓库)。原图在
screenshots/ 下,不在 npm 包内(package.json 的 files 白名单只含运行必需文件)。
侧栏装饰还可以先看后装:仓库内的
tools/theme-bench/ambient-preview.html 以宽窄两种侧栏宽度
并排渲染全部皮肤(该页把 CSS 与场景标记直接读自 lib/client.js,不会与出货版本漂移);
tools/theme-bench/panel-preview.html 则渲染面板本身的卡片顺序与文案
—— 顺序表、内置卡文案、页面样式同样直接读自 lib/client.js。
这是本项目唯一重要的架构决定,结论是前者:
| 维度 | 一个插件 + N 个皮肤数据 | 每个皮肤一个插件 |
|---|---|---|
| 用户装一个皮肤 | 不用动,设置里直接就出现 | 要再装一个包 |
| 设置里的选择器 | 一行列出全部 | 每个插件各自注册一行,UI 抢位 |
| 作者加皮肤 | 改一个 JSON | 新建仓库 + 发 npm + 绑版本 |
| 加载开销 | 一个插件一行 | N 个插件 N 行 |
| 升级 | 一个包对一个 DSH 版本 | N 个包各自绑版本,升级全炸 |
判断准则:有运行时逻辑 / 服务 / Hook → 独立插件;只是数据 / 配色 → 数据文件。
皮肤是纯数据,所以走后者。这也正是官方 ctx.theme 的设计意图——官方 README 原话:"registering one means overriding same-named alias variables"。
官方那一行的选项是写死的常量数组:
// 官方源码 packages/client/ui-theme/src/client/AppearanceRow.tsx
const CUBES = [light, dark, system]
它渲染 CUBES.map(...),从不读取主题注册表。官方 README 也说得很直白:"Third-party themes are an extension point, not a product"。
所以本插件自带入口。
| 位置 | 官方插槽 | 形态 |
|---|---|---|
| 本插件用这个 | sidebar.panellist + main(keyed,同一个 id) | 左栏一个图标 → 主区一整页主题卡片 |
| 备选(未用) | sidebar.footer.action | 齿轮旁的小图标 + 弹出气泡 |
| 备选(未用) | settings.general.item | 设置里一行按钮 |
选第一个的理由不只是位置好:它正是这个应用的"插件"机制——一个插件 = 侧栏一个入口 + 主区一个页面,和 Plugins 页同级。
而且侧栏入口是 list 插槽,一个插件最多占一个座位:这从机制上就否定了"每个皮肤一个插件"。
sidebar.footer.action同样是list,一个插件也只有一个座位,且气泡里放不下预览。设置行则额外需要 settings 域——见下面的踩坑记录。
打开方式:在左侧菜单区,【插件】图标的下方点 主题皮肤(它与「插件」同为面板入口,就在其下一行), 主区显示全部可选主题,点卡片切换,选中态会记入设置。
① 用包名安装(推荐) —— 包已发布到 npm:https://www.npmjs.com/package/dsh-theme-gallery
dsh-theme-galleryWeb / CLI profile 用官方 CLI 装同一个包:
dsh plugin --profile web add dsh-theme-gallery
桌面版的 profile 由 Electron 独占,
dsh plugin --profile desktop …会被拒绝 —— 桌面用户请走上面的界面。
⚠️ 刚发版就想装最新版? DSH 桌面版内置的 pnpm 11 默认带「新版本约 24 小时冷却」的供应链保护: 发布后一天内按包名安装或重装,会静默装到上一版(不报错,不是发版失败,与安装源无关)。 想立即装到刚发布的新版,把包名连版本号一起填(例如新发布的是
0.9.0,就填dsh-theme-gallery@0.9.0,实测可行), 或等约 24 小时后正常安装。
② 下载构建产物(不经过 npm 的等价方式,零构建授权)
dsh-theme-gallery-<版本>.tgz③ 用仓库地址安装(github:renjie2026/dsh-theme-gallery,拉的是源码,不推荐)
只在你想跟源码时用它。本包没有构建步骤,所以不会出现"缺 lib/ 目录"那类失败;
它的代价是 pnpm 可能要求你为构建脚本授权(allowBuilds)。
先说清楚:DSH 桌面版本身不会提示第三方插件有更新,所以「发现新版」和「执行更新」这两件事得靠下面的渠道。
怎么知道有新版本?
| 渠道 | 说明 |
|---|---|
| 插件市场 | 装 DSH-Plugins-Marketplace 后,卡片会显示 「已装 v0.2.0 → v0.3.0」 并给更新按钮 —— 目前最省事的路径 |
| GitHub Releases | 在本仓库点 Watch → Custom → Releases only,有新版本会收到邮件 |
| 对照版本号 | 插件面板右上角显示你装的版本(如 v0.3.0),与 npm 页面 上的版本号直接对照 |
怎么更新?
dsh-theme-gallery → 重启(装上 ^x.y.z 范围内的最新版)dsh plugin --profile web add dsh-theme-gallery版本范围语义:安装时会记录成 ^0.2.0,即 >=0.2.0 <0.3.0 ——
0.2.1 这类补丁会在重装时自动带上;0.3.0 不会(npm 对 0.x 的惯例是
把次版本号变更视为可能破坏性),那种情况按第 2 条显式重装即可。
⚠️ 从 Release 的
.tgz安装的用户没有更新机制(tgz 是一次性快照,只能重新下载)—— 想长期跟更新,建议用包名安装。
| 项 | 说明 |
|---|---|
| 平台 | DeepSeek Harness 桌面版 0.1.7-rc.2(实测通过);同为 web 客户端的 Web / CLI profile 理论可用,但本项目只实测过桌面版 |
| 网络 | 不联网 —— 插件半侧不发起任何请求 |
| 文件 | 包内只有 lib/、schema/、cordis.patch.yml(见 package.json 的 files),不读写用户文件 |
| 界面改动 | 只新增左侧菜单区一个面板入口(在【插件】图标下方);官方「设置 → 通用 → 外观」那一行保持原样——面板里的浅色/深色卡只是调用官方偏好接口,不会往那一行塞任何东西 |
| 本地状态 | 皮肤选择存在 localStorage;主题偏好只写 light/dark/system |
桌面 profile 由 Electron 独占,CLI 会被拒绝:
error: profile "desktop" is managed exclusively by the Electron application
那就手动改 profile 清单(这是官方 profile 的既定机制,不是 hack):
// <DSH_HOME>/profiles/desktop/package.json
// "dependencies": { "dsh-theme-gallery": "^0.3.0" }
// "dsh.profile.bundles": [ ..., "dsh-theme-gallery" ]
cd <DSH_HOME>/profiles/desktop && pnpm install
Windows 上 <DSH_HOME> 默认是 C:\Users\<你>\.dsh。
然后重启。
主题插件最坏的情况是界面进不去。以下四招按"由轻到重"排列,都不需要重装应用。
插件的两个活动层可以用一个配置开关整体停掉,不必卸载。编辑 profile 自己的
cordis.patch.yml(位置:<DSH_HOME>/profiles/desktop/cordis.patch.yml),加:
- id: theme-gallery
name: dsh-theme-gallery
config:
ambient: false # 停掉氛围装饰层与皮肤恢复层
为什么需要这一招:dsh.profile.bundles 不是手写清单 —— 每次插件安装 / 启用 /
优化后,应用都会按 dependencies 里声明了 dsh.bundle.patch 的包自动推导重建它。
所以把一个包从 bundles 里删掉不能持久,会被写回来。上面的开关是插件侧的刹车。
设置 → 插件 里移除本插件,然后重启。这是最干净的做法。
// <DSH_HOME>/profiles/desktop/package.json
// 删掉 dependencies 里的 "dsh-theme-gallery"
// 删掉 dsh.profile.bundles 里的 "dsh-theme-gallery"
cd <DSH_HOME>/profiles/desktop && pnpm install
重启。
这是最可能的"起不来"原因,而且它完全是你自己写的配置造成的。
皮肤 id 绝不能写进主题偏好。ui-theme.config.preference 只接受
light / dark / system:
# <DSH_HOME>/profiles/desktop/cordis.patch.yml
ui-theme:
config:
preference: light # 只能是 light | dark | system
写成皮肤 id(如 shan-qing-ting-cai)时,buildSnapshot() 会抛
theme registry lost 并拒绝启动 —— 因为偏好指向一个(当时)还没注册的主题。
皮肤的当前选择存在
localStorage里,不在preference里。 这是刻意设计: 偏好是启动期读取的,而皮肤要等插件加载后才注册,两者天然有先后。
<DSH_HOME>/profiles/desktop/ 整个目录可以先复制一份再改。出问题时把
package.json 与 cordis.patch.yml 换回去即可。改之前备份是最省事的保险。
DSH 有启动保护。先用它进去,再按上面的「卸载与回滚」处理。
怀疑 fiber pending,去查 inject 与循环等待;不要去看模型或网络配置。
crash-*-web-boot.log(%APPDATA%\@deepseek-ai\dsh-desktop\logs\)里
一条记录都没有,而应用卡在 "Loading plugins..." —— 这就是 pending fiber 的指纹。
历史上撞过三次,都源自 inject:
| 版本 | 错误 | 结果 |
|---|---|---|
| 第一版 | 把 settingsScope 写成硬依赖 | dsh-theme-gallery: pending (waiting for service: settingsScope) |
| 第二版 | 以为 immediately: true 能解决 | 无效,是错的根因判断 |
| 第三版 | 声明的模块没在 dsh.client.inject 里 | 完全没有任何日志 |
Cordis 的 inject 有两种形态:
inject: ['a', 'b'] // 数组 —— 每一项都是【必需】
inject: { a: cfg, b: null } // 映射 —— null 标记该项可选
用数组形态时,拿不到的服务会让 fiber 永远停在 pending,而未激活的 entry 会让整个
web boot 失败。
教训:把自己无法控制的服务写成硬依赖,等于给了它一票否决应用启动的权力。
当前状态:exports.inject = ['slots', 'locale', 'theme'] —— 三者都由静态编入的
UI 包提供,保证存在。另外 package.json 的 dsh.client.inject 声明了提供主题服务的
模块,用来固定加载顺序(漏掉它时不产生任何日志,最难查)。
回归测试锁住了这件事(tests/smoke-host.mjs、tests/check-boot-safety.mjs)。
DSH 有启动保护,弹窗给两个出口:
cordis.patch.yml,所以恢复后要检查
<DSH_HOME>/profiles/desktop/cordis.patch.yml 是否需要补回偏好设置。崩溃详情在:
%APPDATA%\@deepseek-ai\dsh-desktop\logs\crash-*-web-boot.log
日志会逐条列出 pending 的 entry 和它等待的服务名——排查启动问题最快的信息源。
但注意:本插件遇到过一种完全不写日志的启动失败(
dsh.client.inject漏声明), 所以"日志是空的"不能排除插件问题。详见上一节。
$DSH_HOME/settings.yaml这一点与官方文档的默认值相反,值得单独记住:dsh-base 与 dsh-web-app 两个 bundle 都把设置文件 provider 配成了内存模式——
- name: '@deepseek-ai/dsh-settings-file'
path: ':memory:'
所以桌面版里手写 settings.yaml 不生效;应用启动时会把这类文件归档成 settings.yaml.imported,然后继续使用内存状态。控制皮肤选择的权威位置是组合层——profile 的 cordis.patch.yml:
- id: ui-theme
name: "@deepseek-ai/dsh-client-ui-theme"
config:
preference: shan-qing-ting-cai
或者,等插件加载成功后直接用设置界面点选。
(theme-gallery 段仍可写在 settings.yaml 里,但需要 profile 换成文件型 provider;桌面版目前走内存,所以加自定义皮肤请改 lib/themes/*.json 后重跑 npm run embed-themes。)
首次启动前,cordis.patch.yml 里的偏好先留内置值(dark / light / system)。因为 ui-theme 的 buildSnapshot 在偏好指向未注册 id 时会抛错(官方源码里是明确的 throw,不在 try/catch 内):
if (active === void 0) throw new Error(`theme registry lost "${resolvedId}"`)
而 shan-qing-ting-cai 要等本插件的浏览器半侧注册完才存在。确认插件加载成功后,再把偏好改成皮肤 id。
皮肤的价值是整屏覆盖;而整屏覆盖正是长对话难读的原因。所以界面被分成两种状态:
皮肤不只是配色,还把原系统左侧菜单区的元素素材复刻了过来,并给"正在使用"的状态加了标记色。
ambient| 皮肤 | 素材 |
|---|---|
山青婷彩 kind: "shan" | 青山两层 + 山间云雾 + 山脚水面与点水涟漪 + 两只悬停蜻蜓 + 花瓣飘落 |
梦海游鱼 kind: "dream" | 左上柔光辉 + 两道弥散光洗 + 上浮气泡 + 五叶水草摇摆 |
营慕彩云 kind: "caiyun" | 暮色暖光 + 暖金光点 + 三层模糊彩云 + 前后两层漂移云海 + 两只往返漫游的热气球 |
佩安杰心 kind: "jiexin" | 雾山远衬 + 禅意圆相与坐禅人影 + 香炉两缕青烟 + 浮尘光点 + 禅语「自在 · 安顿」 |
琥珀猫咪 kind: "humao"(原创) | 暖阳光晕 + 晒暖窗台 + 坐姿虎斑猫(摆尾 / 抖耳)+ 蜷卧酣睡猫(呼吸起伏 + 小 z)+ 阳光浮尘 |
虎子阿黄 kind: "ahuang"(原创) | 金色光晕 + 田埂 + 中黄田园犬(镰刀尾摇摆 / 歪头 / 铃铛项圈)+ 干草丛 + 缃色皮球 + 蒲公英绒毛 |
大鲸鱼娘 kind: "jingyu"(社区同人立绘) | 入场特效——自窗口右上角画面外俯冲进来、向左下横扫整个工作区、绕一个完整的大圈后落定(身后拖一串水泡、落点一圈很淡的水花),约 3 秒时交叉淡入淡出转成背景壁纸态(右上「深海小窗」立绘 + 半透明应用表面);侧栏另有上浮气泡(7 枚)与两只幼鲸 |
流星白羽 kind: "liuxing"(原创,尚未发布) | 弦月金辉 + 白羽流星低频掠过 + 雁阵缓渡 + 蒹葭摇曳 + 白露霜星 + 远山淡影 |
姑苏繁花 kind: "fanhua"(原创,尚未发布) | 垂柳丝绦 + 桃花枝 + 落英缤纷 + 春水涟漪 + 飞燕横渡 + 罨画远山 |
青冥飞剑 kind: "feijian"(原创,尚未发布) | 悬停剑落定后绕剑柄—剑尖轴缓缓自旋(呼吸荧光晕 + 世界坐标剑穗 + 荧光微尘);另有全屏部分——三剑编队沿用户红笔图的双环轨迹入场(主剑 + 两把伴飞小剑,尾翼=青白主痕/樱粉副痕/残影箭羽/迸散火花,挂在 .dsh-amb-control 全视口层、场景盒之外)+ 四周剑光角饰框;聊天文字区另有宝剑壁纸(body 级 z-index:-2 独立层里的横放古剑,飞剑落定后淡入,正文压在剑上) |
青玉凤剑 kind: "longyan"(原创;显示名 2026-10-01 由龙焰宝剑改来) | 全屏双剑悬空(青玉凤纹系 + 银鎏金流光系两柄透明底古剑,交叠摆位各自缓浮)+ 四重气焰——呼吸辉光、剑刃焰舌、升腾火屑、扫刃辉光;素材带另有青焰辉光 + 能量丝 + 火屑。青焰 #3FE0BB × 鎏金 #E8C25A 的暗色新调色盘(102 token 深色形态);背景壁纸另立独立主题位 |
龙焰宝剑(显示名青玉凤剑(带壁纸))kind: "longyan2"(原创) | 青玉凤剑·整剑版 + 背景壁纸:同一套气焰与入场,A 剑为像素级合成的整剑(断剑延长,凤尾与青焰顺势向剑尖延伸),悬停露柄侧半截;聊天区背景壁纸 = 国风图(白龙+唐装执剑少女+金焰),显示管线照青冥壁纸(body 级背景层 + 可读性幕布 + 水印保底 + 双路半透明地面令牌);卡片序 76(2026-10-01 用户指定:77 与 75 之间) |
素材逐像素复刻自源系统对应的主题动画组件(ShanQingTingCaiAnimation.vue、
DreamOceanAmbient.vue、YingMuCaiYunAnimation.vue、PeiAnJieXinAnimation.vue);humao / ahuang
两套为本插件原创绘制(同一条造色十步法,色相取自中国传统色库)。与原系统有意偏离两处:
pointer-events:none 且置于导航之下。原系统文档记有一条 bug:不透明山形贴在侧栏底部会遮挡最下方菜单项。kind 是数据键而非素材路径——插件只为它真正画得出的场景提供键,写错会在构建期失败,而不是运行时静默不画。
装饰挂在 document.body 上的全屏 .dsh-amb-control 图层里,场景盒再按侧栏几何绝对定位在图层内部——图层与场景盒必须拆成两层,这是本项目花了二十多轮才找到的结论(压在一个元素上时两种形态都不绘制)。这是本插件唯一直接操作外壳 DOM 的地方(侧栏没有装饰插槽,插槽组件会成为列的兄弟而非其背后的图层),因此单独隔离、整体 try/catch:装饰是修饰,绝不能成为故障原因。侧栏定位用三级回退,因为外壳类名是 CSS-module 哈希、不是稳定契约。
先看效果再装:npm run preview:ambient 生成的预览页把 CSS 直接读自 lib/client.js,因此不会与出货版本漂移;两种侧栏宽度并排。
accent侧栏条目与选中对话行在 DSH 里共同读取 --dsw-alias-button-ghost-active-fill/-border/-hover,所以 accent 叠加到这三个 token 上,两者同时变成标记色。
取值遵循来源项目《主题皮肤设计规范(第二区域)》第 123 / 118 行:强调色取本皮肤第一区域的特征色,且禁止引入第一区域不存在的色相。所以
| 皮肤 | 强调色 | 出处 |
|---|---|---|
| 山青婷彩 | #E88BB0 | 蜻蜓粉 |
| 梦海游鱼 | #FFD166 | 夕照金 |
| 营慕彩云 | #FFB347 | 云霞琥珀 |
| 佩安杰心 | #B4653A | 赭陶 |
| 琥珀猫咪(原创) | #CA6924 | 中国传统色「琥珀」 |
| 虎子阿黄(原创) | #F0C239 | 中国传统色「缃色」 |
| 流星白羽(原创,尚未发布) | #F2BE45 | 中国传统色「赤金」(弦月金辉——冷夜场景里唯一的暖色) |
| 姑苏繁花(原创,尚未发布) | #F47983 | 中国传统色「桃红」(桃花正繁——暖忆场景里的花色即accent) |
| 青冥飞剑(原创,尚未发布) | #25C6D0 | 剑光青(靛青 #177CB0 的荧光化提亮,自调——荧光感是这套皮肤的身份) |
| 江畔冬云 | #F2C879 | 冬云暖金 |
| 徐山军月 | #D4B266 | 军月金 |
| 大鲸鱼娘(社区同人立绘) | #5FD9F5 | 鲸鳍水青(深海夜航里唯一的亮青,自调) |
| 青玉凤剑 / 青玉凤剑(带壁纸)(原创) | #E8C25A | 金凤金(鎏金凤纹——同一套双剑素材共用的强调色) |
不是所有主题一律粉——那样恰好违反来源项目自己的规范。两条约束由代码强制:叠加只对活跃主题生效、切走即撤除;不动 brand-primary(否则链接、主按钮、状态徽标会被一起改掉)。
| 状态 | 判定 | 视觉 |
|---|---|---|
| 空对话态 | 会话里还没有消息 | 整屏铺满主题:左侧栏渐变 + Windows 顶部标题栏渐变 + 中间留白也是主题色 |
| 有对话态 | 出现消息后 | 正文套一层提亮卡片(默认 62% 不透明度 / 3px 模糊 / 640px 限宽),四周仍透出主题渐变;左侧栏与顶部保持主题强度,一眼可辨是哪个皮肤 |
card(纯色/拼色 一类)到 0.3.0 为止,每张卡片都是一条 6px 色带,取色由代码从皮肤的 3 个 token 里挑
(brand-primary / label-secondary / state-business-primary),所以任何皮肤都不用额外写卡片信息。
一条色带只能表达"一套配色长什么样",而这一类卡片要表达的是**"这里有多少套配色,点哪个换哪个"**。
所以新增了可选字段 card.rows(不写它就还是那条色带,九套场景皮肤一个字都没改):
卡片上排 15 个可点的色值按钮,5 + 5 + 5:上两排是 10 个纯色方案,最后一排是 5 个拼色方案。
"card": {
"rows": [
{ "kind": "solid", "schemes": ["p-xiang-se", "p-ju-huang", "p-tao-hong", "p-hai-tang-hong", "p-jiang-zi"] },
{ "kind": "solid", "schemes": ["p-song-bai-lu", "p-zhu-qing", "p-cang-qing", "p-dai-zi", "p-xuan-qing"] },
{ "kind": "clash", "schemes": ["p-shi-liu-jin", "p-bao-lan-jin", "p-qing-lian-jin", "p-song-hua-tao", "p-wu-jin"] }
]
}
15 套配色不是 15 个主题。 它们住在 lib/palette-schemes.json,由建期
内联进包里,但不注册进主题服务:所以官方「设置 → 通用 → 外观」的主题列表里不会多出 15 项,
面板头部的"N 款皮肤"也仍然是皮肤数。点一个按钮 = 把该方案的 token 层叠到整屏上,
所选方案记在 localStorage(theme-gallery:palette),绝不写进 ui-theme.preference。
| 规则 | 为什么 |
|---|---|
| 2 或 3 排,最后一排必须是拼色 | 拼色排在最下方才读得出层级;放别处只会像画错了 |
| 一排 1–5 个按钮,等宽 | 5 个是卡片最小宽度(200px)下仍能读出 5 种颜色的上限,第 6 个只剩约 28px,会读成条纹 |
| 每个按钮按宽度分带:纯色格一条带占满;拼色格主色占 2 份、每个次色各占 1 份 | 一眼看出"这一套谁占大头、旁边配了哪些色"。比值由数据算出来(一主一次 = 2/1、一主两次 = 2/1/1、一主四次 = 2/1/1/1/1),不是写死的;画法和点下去的效果取自同一张表,不可能对不上 |
| 每个次色相对主色的对比度 ≥ 2.5:1 | 次色带在最窄的卡片上只有几像素宽,明度接近时整条糊进主色里,没有异常也没有日志。实测反面样本:碧色 #1BD1A5 上的红点 1.14:1、海棠红 #DB5A6B 上的竹青 1.07:1 |
| 深色正文压在方案底色上 ≥ 7:1 | 15 套方案只写三四个色,其余 60 多个 token 由 schemeTokens() 派生;底色与正文的对比度是整屏的阅读下限 |
| 按钮填充色按对比度选(本色 + 深色字 / 本色 + 白字 / 压深后用白字) | 缃色、橘黄、桃红这类亮色做填充时白字只有 1.7–3.7:1,读不清。规则逐个候选试,尽量让按钮留在色库那个名字色上;石榴金显式指定用「胭脂」#9D2933(白字 7.50:1) |
| 15 套全部出自中国传统色库 | zerosoul/chinese-colors 的 src/assets/colors.json,每套都写明「组 + id」出处(见 source 字段) |
15 套色值一览(主色 = 纯色格那一整条带 / 拼色格的第 1 条带;次色 = 拼色格其余各条带。
表由 lib/palette-schemes.json 直接生成,不手抄):
| 位置 | 方案 | 主色 | 次色 | 色库出处 |
|---|---|---|---|---|
| 纯色 1 | 缃色 | #F0C239 | — | 黄 1-9 缃色(浅黄色) |
| 纯色 2 | 橘黄 | #FF8936 | — | 黄 1-5 橘黄(柑橘的黄色) |
| 纯色 3 | 桃红 | #F47983 | — | 红 0-3 桃红(桃花的颜色) |
| 纯色 4 | 海棠红 | #DB5A6B | — | 红 0-4 海棠红(淡紫红色、较桃红色深一些) |
| 纯色 5 | 绛紫 | #8C4356 | — | 红 0-9 绛紫(紫中略带红的颜色) |
| 纯色 6 | 松柏绿 | #057748 | — | 绿 2-30 松花绿(松柏叶的墨绿) |
| 纯色 7 | 竹青 | #789262 | — | 绿 2-3 竹青(竹子的绿色) |
| 纯色 8 | 苍青 | #7397AB | — | 苍 4-3 苍青 |
| 纯色 9 | 黛紫 | #574266 | — | 蓝 3-12 黛紫(深紫色) |
| 纯色 10 | 玄青 | #3D3B4F | — | 黑 7-1 玄青(深黑色) |
| 拼色 1 | 石榴金 | #F20C00 | #FFFFFF #D6ECF0 #EACD76 #3DE1AD | 红 0-5 石榴红 + 金银 8-0 赤金 + 绿 2-14 翡翠色;按钮族用红 0-11 胭脂(白字 7.50:1,而压在石榴红上只有 4.35:1) |
| 拼色 2 | 宝蓝·赤金 | #4B5CC4 | #F2BE45 #EACD76 #D9B611 #FFFFFF | 蓝 3-5 宝蓝(多和小面积纯黄色(金色)配合使用)+ 金银 8-0 赤金 |
| 拼色 3 | 青莲·金玉 | #801DAE | #F2BE45 #FFF143 #3DE1AD #FFFFFF | 蓝 3-19 青莲(偏蓝的紫色)+ 黄 1-0 鹅黄 + 绿 2-14 翡翠色 |
| 拼色 4 | 松花·桃粉 | #BCE672 | #C93756 #057748 | 绿 2-31 松花色(嫩黄绿)+ 红 0-1 樱桃色 + 绿 2-30 松花绿 |
| 拼色 5 | 藏青·鹅黄 | #2E4E7E | #F2BE45 #FFFFFF #FFB3A7 #3DE1AD | 蓝 8-2 藏青(深蓝)+ 金银 8-0 赤金 + 精白 + 红 0-0 粉红 + 绿 2-14 翡翠色 |
两处按用户反馈改过色(2026-09-26):① 原「松花·桃粉」的主色是松花绿
#057748, 与纯色「松柏绿」撞脸(两张卡看着是同一个绿),于是那个墨绿归给松柏绿这一格, 「松花·桃粉」改用松花色#BCE672当主色、只配两个次色(画出来正是 2/1/1); ② 原「乌金·翡翠」是拿玄色#622A1D当"乌"用,观感发闷,整条换成「藏青·鹅黄」。 色库里的「乌金」其实是#A78E44这个金褐色 —— 名字与用途对不上也是换掉它的原因之一。
src/assets/colors.json,
本插件只做取色与派生(每套方案只挑三四个名字色,其余 token 由同一条造色规则算出来);
取色数据在 lib/palette-schemes.json,每套都带 source
记着它在色库里的「组 + id」。色名与色值是作者整理的开源成果,
在此感谢作者 tristan 的整理与开源。da-jing-yu-niang 的工作区壁纸人物,用的是社区项目「Deepseek Whale-chan」的现成角色素材
(副标题 A Little Deeper, A Kinder World):https://github.com/Neko3000/deepseek-whalechan
—— 取该仓库 skills/whalechan-image-character/assets/reference-images/standard/01_gentle_wave.webp
(标准体型正面立姿,1024×1024)。角色 IP 属于原作者:鲸鱼娘形象原案
@上善无形(Bilibili https://space.bilibili.com/4456176)、女仆装设计
@ZipZipPipe(Bilibili https://space.bilibili.com/4168597)、角色卡 mamemily2050
(用户提供的角色设定图作者)。该项目的角色设定与素材以
CC BY-NC-SA 4.0 授权、禁止商用,
商用需另行取得原作者书面许可;本插件是非商用同人作品,不做任何商业使用。
本插件对素材只做了两件事:① 把平涂米色底抠成透明、裁到人物外接框、透明区做去边渗色
(一次性加工脚本 tools/art/whale-maid-from-whalechan.py,
它读取的原图 tools/art/whalechan-01_gentle_wave.webp 与产物
lib/assets/whale-maid.png 都在仓库里,重跑脚本会逐字节复现同一张图;
这两件都不进发布包);② 在 AMBIENT_CSS 里
加一层呼吸微动、身后光晕/上浮气泡,以及入场飞入 → 停留 → 转背景壁纸那套动画与层级
(飞入的水泡尾迹、落地水花、可读性遮罩都是 CSS;半透明「地面」由与壁纸层同生共死的
一张伴生样式表提供,皮肤 JSON 始终是 hex 形状)。人物形象本身未作改绘。
在此感谢 Neko3000 的素材整理,以及 @上善无形、@ZipZipPipe、mamemily2050 的创作。
若原作者对上述用法有异议,请提 issue,我们会立即撤下该素材(可回退到本插件自绘版本)。@linxin666/dsh-pet(作者 @linxin666 及其上游资产作者)启发,
一期挂件的位置持久化也借鉴了它的思路,在此感谢。本插件的实现是独立的:
不注入任何额外服务,「模型生成中」的检测走的是 composer 按钮的无哈希 aria-label(DOM 信号)。如果你是要转载或再分发本插件:色值本身请按上面那条一并保留出处与致谢;
复刻皮肤的场景素材请遵循蜂链商城仓库的许可;
大鲸鱼娘的人物素材(lib/assets/whale-maid.png)请遵循 CC BY-NC-SA 4.0 ——
署名(@上善无形 / @ZipZipPipe / mamemily2050 与 Neko3000/deepseek-whalechan)、
非商用、相同方式共享,三条缺一不可。
这一类卡片不印 description:15 个按钮已经占满卡面,文字会把卡片挤爆。description 仍然必须非空 ——
它照 Schema 的定义只作 tooltip(title