DeepSeek Harness Plugin Hub

发布与管理完整 Harness Profiles,发现适合你的插件。

探索

插件目录环境预设文档中心动态

社区

发布插件联系我们报告问题

相关链接

Plugin Hub GitHubDeepSeek Harness 官方项目系统状态隐私说明
© 2026 DeepSeek Harness Plugin HubPowered byPaxTech

独立、非官方社区项目,与 DeepSeek 官方无隶属、授权或背书关系。

DeepSeek Harness Plugin Hub
ProfilesPlugins分类动态文档登录管理 Profiles
ProfilesPlugins分类动态文档登录
← Plugins
B

dsh-bg-atelier

Bg Atelier

DSH Desktop 底图工坊:静态底图、Wallpaper Engine 实时场景与鼠标视差、场景属性及预设、琉璃卡面和对话特效。

插件会安装到这里;不确定时保持 web。

npx -y @deepseek-ai/dsh plugin --profile web add github:Raylen-berry/dsh-desktop-wallpaper#0b81b0c423f9174329e574a0fbd91d6a5ee18506
README兼容性版本

兼容性与来源证明

Bg Atelier 以 dsh-bg-atelier 发布,当前版本为 1.15.2。Plugin Hub 会校验它的 manifest,并保存精确安装来源,便于复现安装结果。

DSH 兼容范围
*
运行环境
web
发布来源
github
Registry 更新时间
2026/9/28

版本

1.15.2stable
2026/9/28
1.15.0stable
2026/9/28
1.9.1stable
2026/9/24
查看其余 7 个版本收起版本
1.7.0stable
2026/9/22
1.6.2stable
2026/9/14
1.6.1stable
2026/9/13
1.6.0stable
2026/9/13
1.5.5stable
2026/9/12
1.5.4stable
2026/9/12
1.4.1stable
2026/9/11

相关插件

正在加载相关插件…

最新版
1.15.2
DSH
*
HMR
重启进程
Tree shaking
未声明可安全裁剪
解包体积
未提供
文件数
未提供
Surface
web
许可证
MIT
发布源
github
GitHub
★ 0
周下载
0
最近提交
2026/10/11
查看源码 ↗
README Badge

点击下方 Badge 复制 Markdown,粘贴到 README 即可。

这是你的 Plugin?认领权益 · 优先安全扫描

验证 package.json 声明的 GitHub 仓库,即可管理这个公开页面。认领后,Hub 会优先安排当前版本的安全扫描,并在通过后公开展示结果。

认领这个 Plugin →
报告问题

相关插件

继续浏览 ui-customization 分类下经过校验的插件。

Web App@deepseek-ai/dsh-web-appdsh 浏览器界面捆绑包:位于 dsh-base 之上的 Web 补丁层,加上运行时粘合插件(提供前端 dist、Web 界面提示符、bash 运行时变量和 URL 行)Experimental Session Titles Bundle@deepseek-ai/dsh-experimental-session-titles-bundle新的用户提示到达时刷新会话标题。Personalized Recommendations@deepseek-ai/dsh-personalized-recommendations回答下方以卡片形式提供个性化页面和内置插件推荐Whale Widgetdsh-whale-widgetDSH Web 界面右下角的 DeepSeek 余额小鲸鱼挂件:余额/今日已用/峰谷定价、自定义泡泡点击序列(文本/余额/今日/峰谷/图片/随机语句与并列加权选择)、逐行样式与字体、悬浮快捷编辑、音效与每轮消耗、自定义角色/动图/音效、吸附与翻转自定义

README

dsh-bg-atelier · 底图工坊 (DSH 标准插件)

为 DSH Desktop 提供可更换底图与输入框特效的标准 DSH 插件。 随 DSH 启动自动加载,重启后保留(设置持久化到 host 侧文件 $DSH_HOME\dsh-bg-atelier\settings.json)。

安装后即随启动加载:本版是打包进 DSH web profile 的标准插件,开机即生效、可在 设置 → 插件 里开启/关闭。

目录结构

dsh-bg-atelier/
├── index.js          # Host 半端 (ESM): 分类型供图路由 + /bga/wallpapers.json 清单路由
├── client.js         # Client 半端: 图单与图库 / 限定范围换图 / 琉璃卡面 / 特效 / 设置页
├── cordis.patch.yml  # bundle 挂载声明 (让 DSH 启动时挂载本插件)
├── package.json      # npm 插件清单 (dsh.bundle.patch + dsh.client 客户端声明)
├── wallpapers/       # 内置底图目录 —— 每个子文件夹 = 一个"底图类型"(**原始文件**,PNG/JPG 原样,无损)
│   ├── 线稿风/          # 例如: 亚丝娜.png / 青缭.png / …
│   └── 重返未来1999/    # 例如: Vertin.png / 梁月.png / …
├── INSTALL.md        # 安装 / 升级 / 卸载指南
└── README.md

安装(首次)

在 DSH Desktop 的任意会话里让 agent 执行(或直接在宿主 shell 运行):

dsh plugin --profile web add link:D:\DeepSeek\dsh-plugins\dsh-desktop-wallpaper

装完后重启一次 Harness/DSH Desktop,插件即随启动自动加载。 设置页顶栏会多出 底图工坊 入口;侧边栏底部出现「流光宝珠」换图按钮。

发布到仓库后(推荐)改为从仓库安装: dsh plugin --profile web add https://github.com/Raylen-berry/dsh-desktop-wallpaper#main

放入/更换底图(按类型)

已发布图库:共 4 个类型、261 张底图(二次元 2 / 线稿风 5 / 重返未来1999 123 / 高清 131)。 clone 完先在插件目录跑一次 node tools/fetch-wallpapers.mjs(或设置页点「下载底图」)把图取回来,再重启 DSH; 设置 → 底图工坊 → 点类型卡进入图库即可选。图片不进 git(v1.5.5 起改走 Release 资产,见下面 A 节), 所以 clone 只有代码、很快;已发布图片为原始文件(无损,约 7.39 GiB,口径见 A 节)。本地另放的图片不一定包含在发布清单中。

加一个新类型/新图:把图片放进「放图目录」下一个子文件夹 = 一个类型,例如:

$wp = "D:\DeepSeek\dsh-plugins\dsh-desktop-wallpaper\wallpapers"   # 或下面的放图目录
New-Item -ItemType Directory -Force "$wp\重返未来1999"
Copy-Item C:\some\*.png "$wp\重返未来1999\"

host 每次实时解析、按需刷新,设置页点「刷新」即出现新类型/新图(无需重启)。

放图目录解析顺序(首个有图的目录命中,① 最高):

  1. $env:DSH_BG_ATELIER_WALLPAPERS 指向的绝对目录(显式覆盖)
  2. $DSH_HOME\dsh-bg-atelier\wallpapers(推荐,插件启动时自动建好,随时往里丢图)
  3. 插件包内置 wallpapers/(随包分发,当作默认图集)
  4. 工作区相对路径 dsh-plugins/dsh-desktop-wallpaper/wallpapers(旧动态版兼容)

根目录若有散图(旧版遗留)会自动归入「未分类」类型;旧版根目录 URL 仍可访问(host 会自动按文件名在类型里找回),升级不丢当前底图。

高清细分

文件名去掉扩展名后,尾部带这些标记的会自动打上「高清」并可在类型图库内用 全部 / 高清 / 普通 筛选: 高清、_高清、·高清、-高清、(高清)、_4K、·4K、_HD、(HD)、_UHD 等(英文标记需要前置分隔符,避免误伤正常英文名)。 显示名 = 去掉标记后的名字(如 亚丝娜_高清.png 显示为 亚丝娜 + 高清 角标),不会把编号写进显示名。

功能

  • 图库与图单:左侧按全部壁纸、我喜欢、最近使用、自建图单或原文件夹浏览;支持名称/类型搜索和清晰度筛选。
  • 图单:可以新建、重命名、删除;卡片上的心形按钮加入“我喜欢”,加号可收录到一个或多个图单。 支持多选、全选搜索结果、批量加入及移出。图单只存收录关系,原图不移动、不复制;删图单也不删原图。
  • 切换范围:顶部选择图单或文件夹,或在图库里点“设为切换范围”。“换一张”、侧栏宝珠和自动轮播共用这个范围。 浏览其它图单或搜索不会改变切换范围。空图单、缺失文件不会回退到全图库;删除当前切换图单会暂停轮播。
  • 随机规则:在当前范围内采用轮次式 2/3 不重复洗牌,同轮内不重复。范围或成员变化时重新洗牌。
  • 播放顺序与返回(v1.13.0):顶部“播放顺序”可选择随机或顺序,手动、宝珠、自动轮播同步遵循。 顺序播放按图单排列循环,文件夹按图库排列循环,暂时缺失的文件自动跳过。“上一张”沿本次打开页面后的选择记录返回, 再点“换一张”会沿记录前进;换范围后重新记,同一范围内移出的图不会被历史重新带回。
  • 图单排序(v1.13.0):进入图单点“调整顺序”,拖动卡片下方手柄;也可用左右移动按钮,或聚焦手柄按 Alt+左右方向键。 排列自动保存;排序时显示完整图单,暂时停用筛选和多选,避免只对一部分图片排序。再次加入已有图片不会改变它的位置。
  • 设置布局:大幅当前图预览 + 换一张/暂停轮播/喜欢/图单操作;下方分为“图库 / 外观 / 切换 / 动态壁纸”。 文件目录和内置图片下载收进“管理壁纸文件”;外观控件采用统一对齐,支持浅色、深色、窄窗口与键盘操作。
  • 保存与恢复:图单、喜欢、最近 36 张和切换范围随设置保存;保存请求串行执行,失败时显示重试入口。 设置导出/导入同步保留这些信息,以及 WE 模式和画质偏好。大图单允许最多 2 MiB 的设置请求。
  • 自动切换(v1.10.0):开关 + 间隔滑杆 —— 14 档不平均刻度(v1.11.0 起,见下),抽图与「流光宝珠」同一套轮次式 2/3 不重复规则。默认关。定时器只有一根:改开关、改间隔或换图时重起;只调外观不清零。间隔在读秒时还要再钳一次(NaN / 0 / 越界 → 1–120 分钟,再吸附到最近一档)—— setTimeout(fn, NaN) 等于 0ms,那是每秒换几千张图并刷爆 settings.json 的写法。
  • 间隔档位(v1.11.0):1 2 3 4 5 7 10 15 20 30 45 60 90 120 分钟,滑杆给的是等距的 0–13 号档位、 值由表查出(原生 step 只能等比,表达不了不平均刻度)。前 10 分钟占掉 6 档 —— 均匀 1 分钟一档时 「1→10 分钟」这段最常用的区间只占全程 8%,手感上等于没得调。手改过 settings.json 的存入值 (如 47)读写两侧都会吸附到 45,设置文件与界面不会各说一套。
  • 渐变过渡:图库点击、侧栏宝珠、自动换图共用同一套切换控制,默认开启。 连点时当前这段渐变继续完成,只保留最后一次选择,随后从刚淡入的图继续渐变过去; 中间点击不会积压成播放队列。过渡中旧图与下层新图都保持不变,避免半透明旧图下面突然换图。 手动点击会按节奏即时加速正在进行的渐变,最新目标也使用该次点击对应的时长。v1.15.0 的档位为: 两次点击间隔 ≥1500ms → 原设置;800–1499ms → 最长1000ms;400–799ms → 最长500ms;<400ms → 最长300ms。 第一击、停顿 ≥1500ms 后恢复原设置;只缩短、不把更短的原时长拉长。记录点击时刻而非图片解码完成时刻, 所以慢图不会误判为慢点。快速连点会跳过“开始前等待”;自动轮播与启动恢复不参加计频,也不继承快档。 当前动画从现有进度提高播放速度,不重置透明度;同档反复点击不延后完成时刻。上述档位表示完整一段渐变的时长, 已播放一部分的动画只加快剩余部分。每次点击仍推进选图;极快连点中的中间图可能不完整显示,画面加速追上最后一次选择。 下一段的起点禁用 transition 并先显示一帧,再开始淡出,防止浏览器把上一段的透明度从 0 反向动画到 1。 双 rAF 保证起点与终点分帧;从实际提交终点后开始计时,computed opacity 不可见才拆层, 主线程阻塞时不会按插入层的墙钟时间强拆。清空、关闭渐变、WE 接管、插件卸载均取消排队。 系统开启减少动态效果时直接切换。
  • 换图重置自动切换间隔:手动、宝珠、自动换图都从最新切换重新计时; 仅调整暗纱、配色或其它外观参数不重置计时。
  • 后台暂停(v1.15.1):窗口失焦、隐藏或冻结时停止计时并取消未上屏的换图; 回到前台保留最后一张已加载的图,重新计算完整间隔,不补播后台错过的切换。
  • 过渡参数:响应时间 0–1000ms(开始淡出前的等待);渐变时长 100–5000ms。默认 0ms / 900ms。 新图解码成功后才接受切换;加载错误或 15 秒超时保留原底图,避免露出空白背景。 连点只保留最新目标,过期解码结果不会上屏;清空、换范围、WE 接管或卸载时解除旧加载引用。
  • 连点负载控制(v1.15.0):每次点击仍推进选图位置;解码任务串行执行,只保留一个最新待处理目标。 当前渐变结束后才加载下一目标,跳过赶不上显示的中间图,避免原图解码、预览重绘与保存请求堆积。 相同图片共享正在进行的解码;失败或超时保留当前图,有新目标则继续处理。

v1.3.0 起不再提供「对话页固定宽度」:那一节(开关 + 640–3840px 滑杆 + 常用宽度快捷键) 已整体移到 dsh-cache-control 的设置页 「会话策略」→ 对话页。钉的是同一组 --dsh-chat-content-width / --dsh-composer-card-max-width / --dsh-chat-user-width 变量,两边同时开只会互相覆盖,所以本插件这边彻底删净。数值不用重设:cache-control 的 host 半在启动时发现自家 settings.json 缺 chatWidth / chatWidthEnabled,就一次性从 $DSH_HOME\dsh-bg-atelier\settings.json 搬过去并写盘。本插件此后不再碰这些字段。

发布前检查(CI 与本地同一条命令)

push / PR 都会跑 .github/workflows/ci.yml,它只做一件事:npm test。本地跑的就是同一条命令, 不装任何依赖、不联网、不做任何真实下载:

npm ci                         # 首次安装开发测试依赖(React,与宿主 18.3.1 对齐)
npm test                       # = node tools/run-all.mjs
node tools/run-all.mjs --list  # 只看清单:跑哪些、以及哪些被排除、为什么

tools/run-all.mjs 把每套都跑完再汇总,任一套非 0 退出 ⇒ npm test 退出码 1 ⇒ CI 变红。 CI 用 Node 20/22/24 三档矩阵、windows-latest。

本机实测(Node 24.20.0):语法检查 18/18、离线套件 14/14 通过。重点回归:

套件本机结果
tools/test-download-robustness.mjs42 项通过(自带假 HTTP 服务,零请求出网)
tools/verify-dockfx-bounds.mjs全部 PASS
tools/verify-background-lifecycle.mjs后台停表、迟到回调、解码中断、渐变中断、恢复与卸载通过
tools/test-playlists.mjs更名后的收藏、图单、最近使用及构图迁移通过

另用隔离 Chromium 检查后台 10 分钟后恢复、完整间隔重新计时、自动和手动换图的实际截图像素。

未纳入 CI 的步骤(原因同时写在 tools/run-all.mjs 的 EXCLUDED 里): tools/fetch-wallpapers.mjs --check(只读校验本机原图,不联网;要已备好 261 张约 7.39 GiB 底图,图片不进 git ⇒ CI 上必然失败)、 tools/test-served-bytes.mjs(要 wallpapers/ 里的真实图片才能起供图路由断言,离线实测退出码 1)。

换台机器:可迁移性与必须手动的步骤

给后续在任何一台机器上接手的人或 agent:装本插件不需要任何手工点击(不像 dsh-browser-live 要装浏览器扩展),但下面几条必须先看清楚。 (起因:用户 2026-09-12 反馈"工作电脑上传、回家发现可用性很差、必须手动操作"。)

A. 克隆体积(v1.5.5 起:图不进 git,改为 Release 资产 + 按需下载) 已发布底图合计约 7.39 GiB(现 261 张;Release tag wallpapers-v1 与清单同步为 261 个资产),长期放在 git 里会让每次克隆都变成几百 MB(用户换机时"装个插件要拉几百兆"就是这么来的)。 加图后的发版流程:node tools/make-manifest-append.mjs --from <上一版清单> → node tools/make-release.mjs(对账+补传+逐张回验,可断点续传)。 仓库只留 wallpapers.manifest.json(每张图的路径 + 字节数 + sha256),图片作为 Release 资产发布(tag wallpapers-v1):

git clone https://github.com/Raylen-berry/dsh-desktop-wallpaper.git   # 只有代码,很快
cd dsh-desktop-wallpaper && node tools/fetch-wallpapers.mjs            # 从 Release 取回全部(可重入/断点续传)
node tools/fetch-wallpapers.mjs --check                               # 只校验本机现有图(不联网)

画质口径:完全无损 —— 不缩放、不重编码。 Release 资产就是原始文件(PNG / JPG 原样),逐张 sha256 与清单一致。 下载量确实大(7.39 GiB),这是有意换来的:底图是长期资产,宁可下载慢,也不要在存档上留一次有损编码。

显示这一侧现在也不打折(v1.6.1 起):host 供图不设尺寸上限,把原图字节直接送给浏览器 —— 5120 / 7680 长边的超宽屏、8K 屏全都吃满,不会再被 3840 拉成放大模糊(此前 SERVED_MAX_DIM = 3840 会先在宿主里缩到 3840 再送)。代价是浏览器要解码整张 30–44 MP 的图:单张解码后约 120–175 MB 内存、 切图首帧多等几百毫秒 —— 换的是大屏上的清晰度;而且送原图这条路上 sharp 完全不参与, 省掉了一次「解码 + 重编码」的 CPU 与首字节等待。派生图(图库 640 / 当前底图 320 / 类型卡 112 px) 另走一套,不受影响。真要一份轻量版:node tools/compress-wallpapers.mjs 可另生成一套 3840 宽 WebP q92 到 wallpapers_light/(仅供自用,不参与发版)。

回归测试(不用重启 DSH):node tools/test-served-bytes.mjs —— 用假 ctx 调 apply() 把路由处理器抓出来 直接请求,断言原图那条路逐字节等于磁盘文件、?sz=thumb|preview|poster 仍在缩放、404 与路径穿越防护仍在。

设置页里同一个入口是「下载底图」按钮(显示进度、逐张校验 sha256;已存在且校验通过的跳过 ⇒ 断网了再点一次即可)。

下载的健壮性参数(fetch-wallpapers.js 的 fetchWallpapers(opts),host 路由与命令行共用这一份)

  • timeoutMs:单张的时间预算,默认 300000(5 分钟)。超时按"这一张失败"处理并走既有退避重试, 不会让任务永远停在"下载中"。覆盖方式:fetchWallpapers({ timeoutMs: 60000 })。 默认值的依据:清单里最大一张是 63283616 B(60.4MB),5 分钟意味着 ~1.7 Mbps 的慢线也能下完, 而正常家用宽带(20 Mbps 以上)一张只要几秒 —— 既不误杀慢线,也不让真卡死的连接赖着不走。
  • retries:单张重试次数(不含首次尝试),默认 2,必须是非负整数(非法值回落 2)。 retries: 0 表示只试一次,真的不重试。
  • signal:外部 AbortSignal。触发后立即停止且不再重试,错误消息会写明"已取消"。
  • 下载是流式的:边收边写 .part、边累计 sha256,字节数一超过清单值就立刻中止 —— 不会把整张图先读进内存(最大 60.4MB)再校验。校验通过才 rename 到最终路径。

这些行为的离线断言:node tools/test-download-robustness.mjs(不联网,把 fetch 打桩、 写入临时目录,覆盖超时/取消/字节数不符/哈希不符/正常落盘,共 42 条断言)。

加图/改图必须用追加式清单生成器:tools/make-wallpaper-manifest.mjs 是从零重编号的, 一改名或加图就会让既有 wNN 与 Release 里已上传的资产整体错位(贝利尔.png→贝利尔2.png 就撞过 w08/w16),make-release 会因为"同名资产字节数不符"把已传的删掉重传。发版一律走 node tools/make-manifest-append.mjs(默认拿 HEAD 那份清单作基准,按 sha256 把已发布的图绑回原资产名, 只给新图续编 w20、w21…),再 node tools/make-release.mjs 补传差额。

迁移顺序(重要):先把图作为 Release 资产发布并验证下载可用,再把 wallpapers/ 从 git 移除; 反了的话,新克隆在 Release 就绪前一张图都拿不到。图片从 git 移除之前,git sparse-checkout add wallpapers 仍可按需从 git 取图(离线机器适用)。

B. 装(agent 可全自动)

dsh plugin --profile web add link:<你放插件的绝对路径>

link: 挂载 ⇒ 改完即生效。装完必须重启 DSH Desktop:client 半在服务启动时 compose (与 dsh-cache-control 同理,刷新页面无效)。重启会掐断正在跑的会话轮次 ⇒ 让用户自己挑时间。

C. 底图在哪 / 设置在哪

  • 底图在插件目录自己的 wallpapers/<类型>/ 下(原始文件、不进 git ⇒ 换机后先按 A 节从 Release 取回); 往里加图后派生图(640px 图库图 / 112px 类型卡迷你图)会自动生成。
  • 设置(当前底图 / 特效 / 配色 / 卡面不透明度与模糊 / 卡面阴影开关)在 $DSH_HOME/dsh-bg-atelier/settings.json,不在仓库里 ⇒ 换机器后是默认值: 特效回到「流萤」、卡面阴影为开、底图要重新选一张 —— 这是最常见的"装好了但看着没变"。
  • 特效与底图已解耦(v1.5.1 起):没有底图也照样画特效。若在老版本上遇到 "点了清除底图 ⇒ 特效全无",那是 v1.5.0 及以前的旧 bug,升级即可。

D. 已知的宿主坑:插件会被 generation 迁移搬走(本机踩过) 部分 DSH Desktop 版本启动时做 installGeneration 迁移,会把 link: 挂载的插件重新 stage, 期间把一个绝对路径当相对路径拼接 ⇒ ENOENT、迁移被 defer,插件也可能不加载。 本机的处置是给应用 bundle 打本地补丁(把本插件加进 KEEP_IN_SHARED_TREE)——该补丁不在本仓库里, 它属于"每台机器各自的 DSH 应用目录"。识别方法:启动日志出现 migration deferred / could not stage, 或 profiles/web/.generations-deferred.json 反复出现。DSH 每次升级都会覆盖该补丁,升级后要重跑。

F. 设置导出/导入(换机器一键搬配置,v1.5.4 新增)

node tools/settings.mjs export --out D:\bga-settings.json   # 旧机器
node tools/settings.mjs import D:\bga-settings.json --yes   # 新机器(覆盖前自动备份 settings.json.bak-*)

show 看当前值;不带 --yes 是演练模式(只打印将要写入什么)。导入只做表层校验 + 区间钳制 (本插件 host 是原样存取、不 sanitize,所以钳制在这儿做严);底图结构不合法时置空并提示, 底图图片不在导出文件里(脚本会检查本机有没有这张图,缺了就提示去 git sparse-checkout add wallpapers)。 导入后仍需重启。

E. 换机后自查(30 秒)

node tools/extract-real-css.mjs      # 期望 PASS(含数量随屏宽 / 阴影独立开关 / DockFx 真渲染三条)
node tools/verify-dockfx-bounds.mjs  # 期望 PASS

设置页 →「底图工坊」→「对话框」应看到:卡面不透明、卡面模糊、卡面阴影勾选框、 四个特效(流萤 / 气泡 / 落樱 / 雨丝)+ 关闭。

卸载

dsh plugin --profile web remove dsh-bg-atelier

或在 设置 → 插件 里停用/移除该插件后重启 Harness。

技术要点 (debug 备忘)

  • Client 用 window.__ModuleLoader__.load({ id, factory }) 包裹,exports.apply/exports.inject。
  • 底图清单走 /bga/wallpapers.json HTTP 路由(返回 { total, categories:[{name,count,hd,items}] }),不再用运行时-only 的 host.call 桥。
  • 供图 URL:/bga/wallpapers/<编码类型名>/<编码文件名>(旧格式 /bga/wallpapers/<文件名> 仍兼容,自动按文件名在类型里找回)。 调试可直接访问:/bga/wallpapers/%E7%BA%BF%E7%A8%BF%E9%A3%8E/%E4%BA%9A%E4%B8%9D%E5%A8%9C.png(含路径穿越防护,../多余斜杠返回 400)。
  • 样式自包含注入(data-bg-atelier-styles),不依赖 styles 全局。
  • webServer prefix 路由匹配规则 pathname === prefix || startsWith(prefix + '/'),注册路径不带尾斜杠。
  • Host 日志 [dsh-bg-atelier](harness 控制台),Client 日志在浏览器 DevTools。
  • 本地底图去重只能建硬链接,不能删名字:图库列表是实时扫盘(scanTypeDir/listTypeDirs 走 fs.readdir), wallpapers/ 下每个受支持文件都会变成设置页里的一张图 ⇒ 删掉一个重复名字会改变用户看到的列表。 用硬链接则两个名字都还在、共享同一份字节(同一 inode),列表/URL/已有设置里的引用全不变,磁盘只存一份。 工具:node tools/dedup-hardlink.mjs [--dry-run|--pairs];断言:tools/verify-wallpaper-dedup.mjs(在 run-all.mjs 的 SUITES 里)。 ⚠️ node:fs 的 linkSync 在这台机器/卷上会原生崩进程(exit 0xC0000409,STATUS_STACK_BUFFER_OVERRUN, 没有异常栈、进程直接消失),所以工具里建链走 PowerShell 的 New-Item -ItemType HardLink(CreateHardLinkW), 扫描/哈希/判定仍留在 node。
  • 硬链接不影响仓库体积:/wallpapers/ 在 .gitignore 里(底图走 Release 资产、不进 git), 所以去重只省本机磁盘,git clone 的体积一个字节都不变 —— 别把这两件事混为一谈。

版本

  • v1.15.2:新增 16 组普通版与高清版壁纸,共 32 张,发布清单从 229 增至 261 张,全部保留原文件字节。 同步本地已有的「冷周六1」「图图星锑1」编号,保持原下载资产名;旧设置里的当前底图、收藏、图单、最近使用与构图引用自动迁移。

  • v1.15.1:后台暂停自动轮播,恢复时重画当前底图并重新计时;过期计时器、解码及渐变回调不能续播旧任务。 统一“贝丽尔”“以影相之”的拼写,普通版维拉补齐编号 2;已保存的底图、收藏、图单、最近使用和构图随更名迁移。

  • v1.15.0:调节点击节奏边界为 1.5/0.8/0.4 秒,对应原时长/1000/500/300ms。 原图解码改为串行并合并最新目标,渐变过程中不为中间图重绘预览;缓存未变的样式与主题计算、减少图库重绘。 新增隔离浏览器压力回归:验证密集点击仍准确推进选择,同时限制解码并发和界面更新次数。

  • v1.14.0:手动渐变按点击频率分档加速(原设置/1000/600/300ms),当前动画保留进度即时提速,快速连点跳过开始前等待。 同档连点不重新计时;停顿恢复,自动轮播不受影响,原渐变设置不被改写。保留解码等待、独立构图与连续渐变保护。

  • v1.13.0:随机/顺序播放、上一张与前进记录、图单拖拽及键盘排序;每张壁纸独立保存缩放和焦点,渐变两层分别保留构图。 图单顺序、播放模式、独立构图均随设置导出/导入保留。重启 DSH Desktop 后加载新版本。

  • v1.12.0:图单与设置页重构。新增多图单收录、喜欢、最近使用、批量整理和限定图单/文件夹切换;新布局分为四个页签。设置请求上限扩至 2 MiB,保存串行化并显示失败重试。保留连续渐变修复。 升级需重启 DSH Desktop 一次,使客户端与保存路由同时加载新版本。

  • v1.11.0:切换间隔改不平均档位 + 过渡参数可调 + 连点不再闪回 + 换图重起自动切换

    • 连点护栏(实测出来的 bug):连点换图时每一趟都 fadeStop() 拆掉在动的那层、另插一层画同一张旧图, 但那层从 opacity:1 起步 —— 屏幕上那一刻是"旧图 × 当前透明度"(2 秒的过渡里点到第 800ms 就已经只剩 0.6), 于是画面先闪回全不透明再从头淡一趟,而且每次点击都把倒计时归零 ⇒ 用户看到的就是"连点时渐变失效、 点的图迟迟不出现"。真机抓到的证据(MutationObserver 记录 data-bg-atelier-fade 层的增删 + 每 40ms 采 ::after 的 computed opacity):修之前三次连点各产生一次 REMOVE + ADD(opacity:1);修之后只有第一次 ADD,后两次点击不产生任何层增删,透明度单调下降。
    • 拆层也不许信墙钟(第二轮的"卡没渐变,变成闪变"):同一套仪器抓到的另一件事 —— 换图那一帧 主线程被卡 785ms(PerformanceObserver('longtask') 直测),rAF 停 ~950ms,::after 的过渡起手 被推迟到 ~900ms,于是"插入 + 延迟 + 时长 + 200ms"这个墙钟拆层点会落在过渡还没走完的时候: 实测那一刻 opacity 还有 0.24,摘掉它 = 屏幕直接从"0.24 旧 + 0.76 新"跳到全新 = 闪变。 现在拆层前先读 computed opacity(fadeVisible()),没淡完就 200ms 后再看(最多 60 次); 同一次实测里拆层从墙钟的 2434ms 推迟到 3828ms,那一刻 opacity 已经是 0.000005(单调、无回跳)。
    • 换图重起自动切换:判据从"signature 变了"改成"屏幕上的图变了" —— 手动换到满意的那张之后, 间隔从这一张开始算,不会再被刚走完的旧表立刻换走。只调暗纱/配色仍然不重起(免得间隔永远走不满)。
    • 间隔档位:滑杆从「1–120 分钟均匀 1 分钟一档」改成 14 档不平均刻度 1 2 3 4 5 7 10 15 20 30 45 60 90 120。原生 range 的 step 只能等比,所以滑杆本身走等距 0–13, 值由 AUTO_STOPS 表查出(nearestStop 吸附,正好卡中间取小的那档,结果确定)。 Slider(...) 多了一个可选的第 7 参 stops,其余 6 个调用点一行没改。显示文本按值算(30 分钟 / 2 小时), 不是档位序号。坏值(NaN / 非数字)仍兜 30 分钟,兜底值本身也在表里。
    • 过渡参数:新增「响应时间」0–1000ms 与「渐变时长」100–5000ms 两个滑杆,都从 里读、 坏值各有兜底(900ms / 0ms)。响应时间的实现是换图后先按原样多盖一会儿,到点才写终点帧 —— 默认 时走的还是原来那条「下一帧就淡」的路径,行为与 v1.10.0 完全一致。 连换两张时用一个层 token 挡住上一层的迟到回调,不然它会把新层直接推到终点帧(等于不淡)。 渐变时长上限是 2000ms → 5000ms 放开的(实际上限"够慢还能看"就在这里:再长就是两张图长时间叠着); 响应时间那头的钳制从 5000 收成 1000,跟滑杆对齐 —— 否则手改 塞个 3000, 值生效了但滑杆指不到那个位置(拇指贴边、数字却更大)。滑杆上限与钳制上限的一致性由套件守(见下)。

WE 壁纸库(v1.9.1)

可按名称、标签或编号搜索,并按场景、视频、网页筛选;筛选不会更换当前背景。当前背景区可切换实时/静态模式或手动重新连接。

v1.9.0 增加场景属性面板:音量、播放倍率、鼠标视差、翻转、主题配色,以及从壁纸读取的人物、背景、音频等分组。滑块只修改草稿,点击「应用到此背景」才一次性发送;支持放弃未应用修改、按壁纸保存和加载预设及恢复默认,独立保存在 DSH 配置目录 we-scene-properties.json。不修改订阅文件,不把更改应用到 Windows 桌面壁纸。自定义图片等文件属性暂不提供导入;属性里的条件和脚本不会执行。

实时采集提供 30 / 45 / 60 帧目标,默认「均衡」45;显示实际出帧和尺寸。保留原尺寸、原鼠标对齐,不强制缩小采集图像:本机同场景缩放会使帧率降到 11–13,原尺寸 30 帧档约 28.4,45 / 60 帧档约 35,45 档的最长帧间隔更短。帧率取决于机器负载和场景,不能保证稳定 60。视频播放后隐藏后备图,状态更新不再重建主题样式;原生窗口仅变更层级时不重复触发尺寸调整。

从旧版升级需重装原生桥并完整退出、重启 DSH,加载新增属性接口。没有修改 WE 全局画质。

v1.8.1 修复正式桌面权限导致实时场景退回静态图的问题;从 v1.8.0 升级需要重新运行原生桥安装器并完全退出、重启 DSH Desktop。页面内部导航现在保留实时连接,连接失败会留下可查错误。

在「底图工坊 → Wallpaper Engine 库」选择壁纸。场景新增两种模式:

  • 实时 + 鼠标跟随:WE 原引擎运行场景,原生桥把专用窗口画面接入 DSH。保留场景自身的动画和鼠标位置驱动效果,默认 45 fps 目标、可选 30 / 60;需要 WE 已运行,以及已安装并重启生效的桌面桥。
  • 静态近似:保留 v1.7.1 的有界工作线程合成,不需要 WE 运行。实时连接失败时也保留静态画面并显示原因。

实时模式只读取鼠标位置,不转发聊天中的点击和键盘。窗口移动、缩放时跟随;最小化/隐藏释放实时场景,恢复时重连;清除背景、切换壁纸和卸载客户端时停止视频轨道与专用窗口。选择壁纸不改变手动配色,「采用壁纸配色」才会保存明确选择。

原生桥需要 Windows。安装、源代码构建、权限范围、更新后的重装及回退见 we/native/README.md。新增桌面桥后必须完全重启 DSH Desktop,仅刷新页面或重启 Harness 不够。 DSH 更新可能覆盖入口;插件会提示桥未加载并退回静态模式。

库和媒体

支持 workshop 订阅以及 projects/<项目>、projects/<组>/<项目> 本地结构;本地 ID 取相对路径哈希,跳过目录链接,不遍历项目素材目录。图库和媒体共享 60 秒扫描缓存,手动刷新强制重新发现。

WE 状态取进程信息,端口只作诊断。订阅和本地项目均可通过官方 CLI「在 WE 打开」。视频静音循环播放并支持 Range;web 仍为不可点击的沙箱背景,不保证 WE 专有网页 API 兼容。

静态合成仍支持部分 PKG/TEX/LZ4/DXT/PNG,采用单工作线程、八项等待队列、45 秒超时、一分钟失败冷却和尺寸/字节限制。它不完整渲染 scene 动画和特效;实时模式才使用 WE 引擎。旧静态缓存继续兼容,尚未增加源场景改变后的自动失效。

验证(2026-09-24)

  • 18 项语法检查、10 套离线测试通过;新增原生接口边界、安装器幂等性、客户端取消/迟到流/隐藏恢复清理测试。
  • 本机库扫描:22 项,21 个本地项目(含 WE 内置项目)、1 个订阅。
  • 完整 DSH 页面最后 10 秒实测约 30.9 fps(原基线约 28.4),309 帧、报告丢帧 0;独立实例约 35 fps 不代表完整页面性能。曾遇到一次原生窗口关闭,最后复查未再出现,原因尚未确定;短时采样不是长期稳定性保证。
  • 正式插件客户端集成:初次播放 984×660,窗口缩放后 1134×710,最小化恢复建立新流,画面继续更新;输入框命中和清除断言通过。
  • 原生鼠标坐标通过专用 SceneScript 夹具核对。壁纸必须自身支持相应鼠标效果;点击、拖动和键盘交互不会透传到壁纸。
  • 实时模式会额外运行一份场景,性能高于静态图的消耗;多屏跨 DPI、长期稳定性和 4K 压力尚未完整验收。场景声音通过属性面板控制,默认静音。

本地素材不随插件发布;个人配色与当前底图设置不由安装器重置。v1.7.1 已经覆盖前的配色没有历史记录,无法自动恢复。

  • 换图渲染:底图与配色样式分开更新,保留样式节点;外观未变时复用动态样式和主题 token, 保存状态通知不重算背景;稳定图库的排序回调与列表引用,减少纯换图时的图库重绘。 此优化减少样式更新,但不保证超大原图的解码与显存上传完全没有停顿。
  • 图片适应:cover 裁剪 + 九宫格焦点 + 绕焦点缩放(1–2.2×)。v1.13.0 起,在“外观 → 这张壁纸的构图”调整后, 每张图片独立保存,跨图单、重新加载后均会恢复;可单独重置为居中、1×。未单独编辑的图片继续使用旧版默认构图。 渐变中旧、新两张图各自保留构图;调整排队中图片的构图不会改变正在渐变的另一张图。暗纱与界面透明度仍为全局设置。
  • 配色:10 套预设(樱粉/青碧/琥珀/星紫/薄荷/绛红/雾蓝/薰衣草/蜜桃/墨黑)+ 主色/深色自定义。
  • 对话框琉璃卡面:半透明 + backdrop-filter 背景模糊,英雄页/会话页同时生效。
  • 对话框特效(输入框上方那条 dock,v1.5.0 起 8 种 + 关闭):流萤(18 只萤 + 14 颗星 + 2 道流星)/ 气泡(16 个 7–22px 大气泡 + 底部水面辉光)/ 光带扫过 / 星轨环绕 / 浮尘光斑 / 落樱 / 墨韵涟漪 / 雨丝(v1.5.0 新增六个,见下)。极光已于 v1.4.2 按用户要求删除 (盘上存过 aurora 的由 normalizeEffect 自动归回流萤,不需要重设)。 全部纯 CSS 动画(无 JS 定时器),粒子位置按序号确定性生成;不碰消息气泡 (气泡样式归 dsh-cache-control,两边同时改会互相盖)。
  • 特效画布不得产生横向滚动溢出(v1.4.2 的硬约束):.bga-dockfx-in 必须是 overflow:clip, 粒子的漂移行程也必须留在画布内。原因见「版本 · v1.4.2」——飘出画布右缘的萤点会把 [data-conversation-scroll] 的 scrollWidth 顶大,会话区底部那条横向滚动条就会一直频闪。
  • 滑杆:暗纱 / 透光 / 卡面不透明 / 卡面模糊 / 缩放 / 切换间隔(14 档不平均:1 2 3 4 5 7 10 15 20 30 45 60 90 120 分钟)/ 响应时间(0–1000ms)/ 渐变时长(100–5000ms)。
  • 设置持久化到 host 侧文件 $DSH_HOME\dsh-bg-atelier\settings.json,重启 DSH 后保留上次选择。
  • STORE
    0ms
    settings.json
  • 取值格定宽(同上,观感修复):滑杆右边那个数字以前是裸文本,0 毫秒 → 950 毫秒 → 1 秒 字数一变就把同一行后面的控件挤着横跳(响应时间旁边紧挨着渐变时长)。现在统一包进 .bga-val: min-width:58px + 右对齐 + nowrap + tabular-nums(等宽数字,连 1 和 8 的字宽差也不抖)。
  • 设置导入(tools/settings.mjs)同样吸附档位:手改的 47 进 settings.json 会落成 45。 顺手修掉同一处的假警报:老版本文件缺新字段不再喊"不是数字"(那读起来像用户文件坏了), 只有写了非数字才留话。
  • 验证:tools/verify-auto-fade.mjs 从 6 组扩到 8 组(新增"档位滑杆:等距 index → 查表取值 / 表外值吸附 / 显示分钟与小时"和"响应时间与渐变时长:延迟期间不动、到点才淡、连换不串层");另加离线套件 tools/verify-settings.mjs(3 组:档位吸附 / 新字段钳制 / 老文件兼容 —— settings.mjs 里那张 14 档表是 client.js AUTO_STOPS 的副本,得有东西盯着)。跑 npm test:语法门禁 18/18、套件 11/12, 唯一红的仍是本机预存在的 tools/test-we-routes.mjs(只加载未被本版改动的 we/routes.js + we/jobs.js)。
  • v1.10.0:自动切换(间隔可微调)+ 全局渐变过渡

    • 自动切换:设置页新增「自动切换与渐变」一节 —— 开关 + 间隔滑杆 1–120 分钟、1 分钟一档(默认关)。 抽图沿用宝珠的轮次式 2/3 不重复规则。定时器一根、模块级,signature(开关 + 间隔)没变就不重起: 否则 watch 里每次手动换图都会把计时清零,间隔永远走不满。间隔在读的时候再钳一次 (NaN / undefined / Infinity / 非数字字符串 / 0 / 负数 / 越界 → 1–120 分钟)—— setTimeout(fn, NaN) 退化成 0ms 是每帧换图的死循环,不能只靠滑杆范围兜底。 自动换图那一次换完强制重起(autoTick 里 armAuto(true)):池子为空或取图失败也不该让自动切换悄悄停掉。
    • 渐变过渡:抽出一个 bgLayerCss(sel, …)(::before 与 ::after 共用同一套 cover / 焦点 / 缩放 / 暗纱配方), 换图时把上一张画在 body::after、下一帧写到 opacity:0(900ms 后拆层)。同帧写两个值会被合并成一帧、 不动画,所以终点值必须等下一次 rAF。默认开,设置页一个开关控全局;prefers-reduced-motion: reduce 时不加 transition(直接切)。全局生效的实现方式是只接一个口:各换图入口(图库点击 / 宝珠随机 / 自动切换) 本来就都落进 STORE 订阅,过渡挂在那一条订阅上即可,换图入口零改动 —— 不是给某条路径单独加的特效。 两层都是 position:fixed 伪元素,撑不大任何祖先的 scrollWidth,v1.4.2 的横向滚动条约束照旧安全。
    • 换图前先解码(同一版的"自然"补丁):各换图入口统一收进 setWallpaper(item) —— 先 new Image() + decode() 把新图备好再切。不等它解码就切,::before 还没有帧、上一张正在淡出 ⇒ 中间几帧透出深色底 (先变暗再回来)。失败 / 超时(1.5s)照旧切,swapSeq 保证后点的快图不被先点的慢图盖回来。
    • 迁移工具跟着改:tools/settings.mjs 的 DEFAULTS / RANGE 补上 autoOn / autoMin / fadeOn (validate() 从 DEFAULTS 起步且会丢弃未知字段 ⇒ 不补的话导出的设置换机器导入会静默回默认), 顺带修正 v1.5.4 起就没跟上的 pluginVersion 字面量。
    • 验证:新增离线套件 tools/verify-auto-fade.mjs(已登记进 tools/run-all.mjs,6 组断言:间隔钳制 / 开关与 signature 不重起 / autoTick 重新起表 / 渐变层建拆与两帧 / dynamicCss 的 ::before 配方逐条不变 / 换图前解码), 连同原有套件跑 npm test:语法门禁 18/18、套件 10/11(唯一红的 tools/test-we-routes.mjs 是本机预存在问题, 它只加载未被本版改动的 we/routes.js + we/jobs.js,与本版无关)。
  • v1.9.1:壁纸库支持名称、标签、编号搜索及类型筛选,列表独立滚动;当前背景、模式与重连入口集中显示。卡片支持键盘选择,预览延迟加载。属性区增加「放弃修改」,改回已应用值后自动清除未保存标记;操作按钮放到分组之前。拆分库卡片与播放控制组件,取消过期扫描和卸载请求,按钮状态统一交给 React 管理。保持实时画面、鼠标坐标与原有对话特效不变。

  • v1.9.0:增加场景属性和命名预设、30 / 45 / 60 帧目标与实际帧率显示;减少重复主题更新和窗口尺寸调整。

  • v1.8.0–1.8.1:WE 原生场景接入、真实鼠标坐标对齐及受限采集权限修复;保留静态近似回退。

  • v1.7.1:修复分组本地项目扫描、进程状态显示和自动覆盖手动配色;静态合成改为有界工作线程,图库增加扫描缓存。

  • v1.6.2:下载健壮性(fetch-wallpapers.js,host 路由与命令行共用这一份)

    • retries 判定从 opts.retries || 2 改成 Number.isInteger(x) && x >= 0 ? x : 2:原先传 retries: 0(意图"不重试") 会被 0 || 2 变成 2,实际仍重试两次 —— 现在零次重试真的生效,非法值(负数/小数/非数)回落 2。
    • 新增单张时间预算 timeoutMs(默认 300000,见上文):超时算一次失败、走既有退避重试,不再让任务长期停在"下载中"。 新增外部取消 opts.signal:触发后立即停且不重试,错误消息标明"已取消",不会误报成"重试耗尽"。
    • 改为流式下载 + 边下边算 sha256:res.body 异步迭代,字节数一超过清单值立刻中止,不再 arrayBuffer() 整张读进内存 (最大一张 60.4MB);校验通过才把 .part rename 成最终文件,失败则清掉 .part。失败分类:HTTP / 字节数不符 / sha256 不符 / 超时 / 已取消。
    • 验证:新增离线断言 tools/test-download-robustness.mjs(42 条,把 fetch 打桩、写临时目录,不联网)。 同一条断言集在改动前的 fetch-wallpapers.js 上跑:28 通过 / 14 失败;改动后 42 / 42 通过。 其中"字节数超长立即中止"那条最直观:服务端发 12.5MB,改动前消费 100.0%(全读完),改动后只消费 19.2%(2.5MB) 就中止。 既有工具回归:test-served-bytes.mjs、verify-dockfx-bounds.mjs 全通过;fetch-wallpapers.mjs --check 报"全部 39 张都在且校验通过"。
  • v1.6.1:供图不再限 3840 —— 超宽屏直接吃原图

    • SERVED_MAX_DIM 3840 → 0(不设上限):真正使用时那条路直接把原文件字节送出去 —— 不缩放、不重编码, sharp 完全不参与(省掉一次「解码 + 重编码」的 CPU 与首字节等待)。5120 / 7680 长边的超宽屏不再被放大糊。
    • 送原图那条路不进内存缓存:servedBufferCache 是个无界 Map,39 张合计 820 MB(高清那 20 张占 764 MB), 全缓存住就等于让一个换底图插件常驻 820 MB 内存 —— 而它省下的只是 OS 页缓存本来就兜住了的读盘。缩略图那条路照旧缓存。 (更正:此条原先写「约 1.5 GB」,那是把 40–60 MB 套到全部 39 张上的口算错误。真实最坏情况是 39 张字节之和 820 MB;而旧代码缓存的是缩到 3840 之后的字节,实测约占原体积 25% ⇒ 最坏约 247 MB。两者都不是 1.5 GB。)
    • 代价(如实记):浏览器要解码整张图 —— 30–44 MP 单张解码后约 120–175 MB 内存,切图首帧慢几百毫秒。
    • 验证:新增 tools/test-served-bytes.mjs(假 ctx 调 apply() 抓路由处理器直接请求,不用重启 DSH)。 实测原图路:楪祈 27.45 MB / 小瑞安侬 53.88 MB / 梁月 4.38 MB,sha256 与磁盘文件逐张相同; ?sz=thumb|preview|poster 仍在缩放;不存在的图 404、路径穿越 400。
    • ⚠️ 两件事要知道:① 生效要重启 DSH Desktop(改的是 Host 半);② 浏览器对同一个 URL 的旧 3840 图 可能还缓存着(host 给原图 max-age=3600,客户端拼 URL 时不带缓存破坏参数)⇒ 重启后先 Ctrl+Shift+R 硬刷一次。
  • v1.6.0:补齐此前漏发的 20 张底图(共 39 张,全部无损原图)

    • 补齐 20 张从没发过 Release 的图(9/12 的梁月 / 无名者 / 小瑞安侬 / 哑谜1 / 哑谜2 与 9/13 的 贝丽尔1 / 贝丽尔3 / 贝丽尔4 / 惠姑 / Vertin,各含普通 + 高清两份)—— 在此之前清单里有的图远端没有, 别的机器点「下载底图」会恰好在这 20 张上 404。
    • 画质口径定死为无损:Release 资产一律是原始文件,不缩放、不重编码。已发布的 w01–w19 逐张按 sha256 核对确认与本地原图字节相同 ⇒ 只补传了新增的 20 张(487 MB),tag 续用 wallpapers-v1。 (一度做过 3840 宽 WebP q92 的有损版并发成 wallpapers-v2,已按"要无损"的要求连同该 Release 与 tag 一起删除。)
    • 贝利尔.png 已改名 贝利尔2.png(4x 版同步改名),清单里的路径跟着更新。
    • 新增 tools/make-manifest-append.mjs:追加式清单生成器 —— 按 sha256 把已发布的图绑回原资产名, 只给新图续编编号。直接用 make-wallpaper-manifest.mjs 是从零重编号,会把已上传的资产全部冲掉。
    • 另留 tools/compress-wallpapers.mjs:想省下载量的人可自行生成一套 3840 宽 WebP q92 到 wallpapers_light/, 仅供自用、不参与发版。
  • v1.5.4:粒子数量随画布宽度走(密度不再随屏宽变)+ 卡面阴影独立成开关

    • 数量适配屏宽(用户 2026-09-12:"如果你限定数量,在我小屏显示的时候,密度就会很大, 你现在需要全改数量为适配屏宽的类型了")。做法:每个特效定义一个间距(px/颗), 数量 = round(画布宽 / 间距) 再夹上下限,间距按"本机画布 985px 下当时定过的数量"折算 —— 大屏观感与以前完全一致,小屏按比例减少: 流萤 54.7px/只、星 70.4、气泡 70.4、落樱 70.4、雨丝 22.4。 实测(tools/extract-real-css.mjs 用测试缝驱动真函数): 985px ⇒ 萤18 星14 气泡14 落樱14 雨丝44;400px ⇒ 7/6/6/6/18;1600px ⇒ 29/23/23/23/71; 雨丝间距在 400–1600px 全区间恒为 22.2–22.5 px/条 ⇒ 密度不随屏宽变(120px 触下限、4000px 触上限)。
    • 实现要点:规则数组改为可重建(regenerateParticles()),STATIC_CSS 由常量改成 函数 staticCss()(每次重建都重读数组,DOM 节点数也跟着 XXX_RULES.length 变); 画布实宽由 DockFx 每次渲染后与 window.resize(200ms 去抖)量取, 变化超过 24px 才重建样式表(拖窗口边缘不会一帧重建一次); 重渲染走新增的 STORE.touch() —— 只通知、不写盘(画布宽度是运行时事实,不该落到 settings.json)。
    • 卡面阴影独立开关(用户:"关闭特效时会把对话框阴影也关了,这个还是新开一个开关(不要太大)控制阴影吧"): 原来阴影拼在 effectCss 的特效分支里,选「关闭」就一起没了。现在拆成 cardShadow(只管那两道深色阴影)/ effect(只管主色辉光),合成一条 box-shadow 写出 (两条同选择器规则是互相覆盖、不是叠加,必须一次拼好),设置页「对话框」里多一行小勾选框 (.bga-tiny,13px 原生 checkbox,符合"不要太大")。 实测:特效关闭 + 阴影开 ⇒ 阴影仍在;阴影关 + 雨丝开 ⇒ 雨丝辉光仍在、阴影没了。
    • 另:模块新增 exports.internals 测试缝(与 dsh-cache-control 同套路),上面两组数字都由 tools/extract-real-css.mjs 驱动真函数量出来的,不是手算的。
  • v1.5.3:雨丝加密提速 + 落樱/雨丝改等分格子 + 气泡修"停车待发"

    • 落樱与雨丝的横向位置从纯 prand 抽样改成 spread() 等分格子 + 格内抖动: 均匀分布 ≠ 看起来均匀,样本一少必然成团(用户两次反馈"局部密度过大")。 实测相邻间距:雨丝 0.7–3.4(均值 2.1,最大仅 1.6 倍;改前是均值 4 倍)。
    • 雨丝:条数 30 → 44、落速 1.5–2.6s → 0.85–1.5s、延迟改负(切换即满屏,不再逐条起跑)。
    • 气泡:16 → 14;修「刚切换时气泡停在底部等发车」——真因是正延迟 0–7s 期间 .bga-bub 没写 opacity:0,气泡带着边框实心停在那儿;改成负延迟 + 补 opacity:0 双保险。
  • v1.5.2:定稿四种 + 卡面可辨识化 + 落樱/雨丝调参(全部按用户 2026-09-12 逐条要求)

    • 只留 落樱 / 气泡 / 流萤 / 雨丝,删掉 光带扫过 / 星轨环绕 / 浮尘光斑 / 墨韵涟漪: 选项、EFFECT_IDS、effectCss 分支、DockFx 分支、STATIC_CSS 规则与关键帧、dustRules() 全部删净 (盘上存过这四个 id 的由白名单自动归到流萤)。tools/extract-real-css.mjs 增了反向断言: 这四个 id 若再出现在 EFFECTS 或代码分支里,直接 FAIL。
    • 卡面可辨识化(用户:"有时因为全透明看壁纸,确实分不清对话框"):把墨韵涟漪那条 0 0 30px var(--bga-deep-glow)(alpha .5)削浓度后拆成两道,拼在四条特效各自的主色辉光之前 —— 0 1px 2px var(--bga-card-edge)(接触阴影,.34,负责把边勾出来)
      • 0 10px 28px var(--bga-card-shade)(环境阴影,.30,负责把卡面从底图上托起来)。 两个变量由 dynamicCss 按当前配色写入 :root(与有没有底图无关)。
    • 落樱(用户:"数量少了些许、体型有点大 ⇒ 缩小叶子、加点数量,注意不是密度"): 叶子 7–12px → 5–8px(面积约降到 45%)、数量 9 → 14。数量 +56% 而单叶面积 −55%, 所以观感是"叶子多了、不是变密了"。
    • 雨丝(用户:"粗细刚好、数量太少,像空调外机滴水中头奖 ⇒ 加点密度"): 只加条数 12 → 30,跨度不变、粗细仍 1px、落速与长度区间不动 ⇒ 同期在落的雨丝约 2.5 倍。
    • 验证(越界余量按会话列宽 640–3840 全区间算): extract-real-css.mjs PASS(EFFECTS 5 项 / 关键帧 16 定义 14 引用自洽 / 流萤 18·星 14·气泡 16·落樱 14·雨丝 30 全部 0 越界,最紧余量 18–48px); verify-dockfx-bounds.mjs PASS。预览页 tools/effect-candidates.html 同步: 改成真底图背景 + 顶部加了「卡面无阴影 vs 有阴影」对比条,并把落樱/雨丝按新参数重画。
  • v1.5.1:堵掉「底图一被清掉、8 种特效一起无声消失」这个陷阱(用户 2026-09-12 实测反馈)

    • 症状:设置页里点了「清除底图」之后特效全部不见(连底图背景也没了)。 定位:$DSH_HOME/dsh-bg-atelier/settings.json 里 wallpaper 变成 null, 而 DockFx 与 dynamicCss 当时都拿 s.wallpaper 当前置条件 ⇒ 特效与底图被绑死在一条判断里。
    • 修法一(解耦):DockFx 不再要求有底图(只剩 s.effect === 'off'), dynamicCss 里的 effectCss(...) 也移出 if (s.wallpaper) 块 —— 特效画在输入框上方那条画布上、配色来自 :root 上无条件写入的 --bga-accent, 跟有没有底图本来就无关。卡面染色(glassCardCss)仍然只在有底图时才加。
    • 修法二(写盘闸):新增模块级 stateLoaded,没成功读到过设置就拒绝写盘 (save() 开头直接 return),并且只认"至少对上过一个认识的字段"的响应 (拿到 {} / 路由还没就绪都算没读到)。少了这道闸,一个设置还没拉回来的客户端 随手点一下任何开关,就会把自己那套默认值整份 PUT 覆盖掉真实配置 —— dsh-cache-control 早就有这道闸(它的 loaded),本插件一直缺。
    • 两处都只动 client.js 与版本号,需要重启才生效;被清成 null 的 wallpaper 是数据不是代码,得重新选一张底图(本次已由我按原值写回「线稿风 / 月薔薇(ヒトこもる)」)。
  • v1.5.0:对话框特效从 2 种扩到 8 种(按用户要求:6 个候选全做成设置页可点选项,逐个切着挑)

    • 新增 光带扫过 / 星轨环绕 / 浮尘光斑 / 落樱 / 墨韵涟漪 / 雨丝,规则同样由 prand(i) 确定性生成 (dustRules(7) / petalRules(9) / rainRules(12)),DOM 由 DockFx 按 s.effect 建节点, 卡面辉光在 effectCss 里各给一档(一律比流萤轻 —— 这几条是"安静"取向,辉光抢戏就违背选它的理由)。
    • 星轨环绕踩到的坑(实机抓的,别再改回去):offset-path: ellipse(38% 26px at 50% 62%) 里的百分比 是按元素自己的 border box(4px 火花)解析的,不是按画布 ⇒ rx ≈ 1.5px, 三颗火花只在画布最左边上下抖、根本不成轨道。改成 ellipse(calc(var(--dsh-composer-card-max-width,748px) * .38) 26px at calc(... * .5) 56px) 之后实测横向行程 712px(原来约 3px),仍留 110px 左边距、0 越界。
    • 验证:tools/extract-real-css.mjs(把 client.js 当模块跑起来抽真样式表 + 关键帧双向核对 + 按真规则算粒子越界,PASS)与 tools/effects-live-check.html(真样式表 + 真类名在真浏览器里量 行程与可见性:8 个特效全部 moved 满额、opacity 区间非零、除"流星起点 / 气泡水面"这两处 设计上就超出画布的,其余 0 越界)。
    • 两个 dev 脚本都在 tools/,不在 npm 包的 files 白名单里,不会随包分发。
  • v1.4.2:修「对话区底部那条左右滑动的滑块一直频闪」+ 按用户要求删掉极光

    • 根因(真浏览器实量,不是推断):.bga-dockfx-in 原来是 overflow:visible,而粒子/流星 都是 left% + translate 漂移 —— 飘到画布右缘之外的萤点(bga-wander1 最远 +260px)把外层 [data-conversation-scroll](overflow:auto)的 scrollWidth 顶大。实测: scrollWidth 在 1139 ↔ 1209 之间反复变、横向滚动条高度 0 ↔ 8px 反复出现 ⇒ 会话区底部那条横向滚动条滑块一直在闪(30ms 采样 2.5s 抓到 2 次通断)。 逐元素定位抓到的越界元素稳定是 .bga-fly.f13 等萤点(overflow-x 溢出 1–4px 起,随漂移增大)。 不是 dsh-cache-control(会话策略)的问题:那边只写 --dsh-chat-* 宽度变量,不产出任何绝对定位粒子。
    • 修法:① .bga-dockfx-in 改 overflow:clip(不生成滚动容器、不顶大祖先 scrollWidth, 画布本身 height:0 也不影响纵向布局);② flyRules() 改成按位置选漂移方向 —— 左半区的萤只向右漂、右半区只向左漂(新增镜像关键帧 bga-wander1L/2L), 可见行程因此全落在画布内,不会被 clip 硬切;③ bga-meteor2 起点 right:-6% → right:0。
    • 修后实测(把新规则注入真页面量 6s):scrollWidth 恒为 1139、横向滚动条恒为 0、 通断 0 次,且 18 只萤没有一只越出画布(最右 1245px < 画布右缘 1316px)⇒ 观感不变。
    • 删掉极光:三团光雾同样靠 translateX 漂移出画布(同样有频闪嫌疑),观感也和琉璃卡面辉光重复。 同时删掉 @keyframes bga-cardbreath、bga-aurora1/2/3、.bga-aur/a1/a2/a3、 effectCss 的 aurora 分支、DockFx 的 aurora 分支、设置页「对话框」说明里的「极光」字样。
    • 候选特效留档:tools/effect-candidates.html(6 个纯 CSS 候选并排预览,只在开发时看,不进 npm 包)。
  • v1.4.1:特效按反馈收敛(撤声波、气泡加重、流萤加密)

    • 撤掉 声波:一排音柱在输入框上跳动,看着像进度条,和对话场景不搭。盘上存过 wave 的 由 normalizeEffect 白名单自动归回 流萤,不需要重设。
    • 流萤加密度:10 只萤 / 6 颗星 → 18 只 / 14 颗星,第二道反向流星(bga-meteor2), 萤点辉光 9px 2px → 12px 3px、星级辉光 5px 1px → 7px 1.5px。 粒子规则改由 flyRules()/starRules()/bubRules() 按序号生成,位置/时长/延迟取自 prand(i) (对同一 i 永远同一值)——这里绝对不能用 Math.random:换配色、换壁纸都会重建整张 静态样式表,随机数会让萤点每帧乱跳位。
    • 气泡加重:8 个 5–11px → 16 个 7–22px;描边 1px → 2px(写 1.5px 在 DPR1 下被 舍回 1px,实测计算样式就是 1px,等于白写);新增外辉 + 内阴影高光;升起 74px → 92px、 周期 9s → 5.2–10.2s 更快更活跃;底部铺一层"水面"辉光带让气泡有出处; 卡面辉光由单层 0 0 18px .14 改为双层 0 0 26px .22 + 0 0 64px .1。
    • 验证:03-调试临时\verify-bga-trim.mjs 16 项(含"三种特效、无声波"、"无 bga-eq/EQ_BARS 残留"、 "密度 18/14/16");03-调试临时\smoke-bg-poster.mjs 12 项(派生图链路复跑未回归)。 另外在真 Chrome 里量 03-调试临时\bga-fx-sample.mjs 生成的样张计算样式,实测 fly=18 star=14 bub=16 eq=0、气泡尺寸 9–20px、样式表里已无 .bga-eq 规则。
  • v1.4.0:图库看得更清 + 对话框特效扩到四种

    • 设置页图库主图由 48px 占位图换成 640px 派生图(webp q86,实测每张 17–45 KB、生成 54–321 ms), 类型卡迷你图由 48px 提到 112px(q80)。派生图落盘在 $DSH_HOME\dsh-bg-atelier\{previews,posters}\,只生成一次;源文件改动(大小/mtime 变化)后 key 变化、旧图自动失效重生成,不用手工清缓存。
    • 新增图自动生成派生图:插件启动后延时后台补齐缺失的派生图;每次设置页打开/刷新 (/bga/wallpapers.json)之后再 debounce 补一次 —— 新丢进放图目录的图不用等第一次点开就缩好。
    • 对话框特效从 1 种扩到 4 种:流萤(原样)/ 极光(三团光雾漂移 + 卡面呼吸辉光)/ 气泡(底部升起、到顶消散)/ 声波(14 根错拍音柱)。全部画在输入框上方那条 dock 画布上, 纯 CSS 动画(无 JS 定时器),且不碰消息气泡(气泡样式归 dsh-cache-control)。
    • 目录改名:dsh-plugins/bg-atelier → dsh-plugins/dsh-desktop-wallpaper(与 GitHub 仓库名一致)。 包名仍是 dsh-bg-atelier,安装/升级命令不变;已装 link 的 profile 需要把 profiles/web/package.json 里的 link 路径一并改掉(见安装一节)。
  • v1.3.1:与 dsh-browser-live 叠列模式协同 —— 宝珠只提供被动 CSS 变量 --bga-orb-dx / --bga-orb-dy(平移让位、不改布局盒),几何一律由 browser-live 单点写入, 避免两边各自周期测量互相打架;新增壁纸类型「重返未来1999」及「高清」两张。

  • v1.3.2(2026-09-11 修):宝珠从"拟球"变成圆角方块。根因不在本插件 —— DSH 主题自带一条全局规则 @supports (corner-shape:superellipse(1.5)){:root{--dsw-corner-shape:superellipse(1.5)}*,:before,:after{corner-shape:var(--dsw-corner-shape)}}, 即给所有元素设了方圆角(superellipse(1.5),新版 Chromium 支持 corner-shape 后开始生效); 凡是 border-radius:50% 的"真圆"都会被画成方圆块。宿主自己的圆形控件都显式写了 corner-shape:round 做豁免,本插件此前没写,于是只有宝珠中招(🌐 那个按钮的底是 background:transparent,看到的是 emoji 字形,所以它照样圆)。 已给本插件所有真圆补上 corner-shape:round:宝珠、色点、焦点点、转圈、缩略图上的 ::before 转圈、流萤/星光/气泡/极光/水面等特效粒子。旧内核不认这条属性会自动忽略,无副作用。 排查用的对照实验:同一页面渲染 round / superellipse(1.5) / superellipse(2) / superellipse(4) 四种 border-radius:50% 方块,长得和你截图里那颗"圆角矩形"一致的是 superellipse(1.5)。

  • v1.3.0:职责收敛 —— 「对话页固定宽度」整节(开关、640–3840px 滑杆、常用宽度快捷键、 钉 --dsh-chat-* 三个变量的实现与补写观察器)移交 dsh-cache-control(设置页「会话策略」对话页), 客户端状态里不再有 chatWidth / chatWidthEnabled,dynamicCss 也不再输出 :root{--dsh-chat-user-width…} 兜底;本插件只剩底图 / 配色 / 卡面 / 特效。旧值由那边启动时一次性搬走,用户无需重设。

  • v1.2.0:底图工坊性能与体验 —— 图库只加载缩略图(host 缩略图改强缓存、原图点选后才加载)、 图库网格 React.memo 隔离 + 加载转圈动画;对话页宽度上限提到 3840px 并加快捷按钮, 滑杆拖动改为局部即时预览、松手才保存(不再逐格重渲染)。

  • v1.1.0:底图按类型子文件夹组织,设置页改为 类型页 → 类型内图库 两级浏览;类型内支持 高清/普通筛选(文件名高清标记自动识别)+ №编号 角标;换图宝珠改为跨全部类型的 2/3 不重复轮次洗牌;旧版根目录 URL/散图平滑兼容。

  • v1.0.0:由「动态 cordis_define 加载」改为「std DSH 插件打包 + profile 安装」,随启动自动加载, 设置持久化;host 改用 Node fs,新增 /bga/wallpapers.json 清单路由。