DeepSeek Harness Plugin Hub

Publish and manage complete Harness Profiles. Discover Plugins for your next setup.

Explore

PluginsPresetsDocsNews

Community

Publish a pluginContactReport an issue

Resources

Plugin Hub on GitHubDeepSeek HarnessSystem statusPrivacy notice
© 2026 DeepSeek Harness Plugin HubPowered byPaxTech

Independent and unofficial. Not affiliated with, authorized by, or endorsed by DeepSeek.

DeepSeek Harness Plugin Hub
ProfilesPluginsCategoriesNewsDocsSign inManage Profiles
ProfilesPluginsCategoriesNewsDocsSign in
← Plugins
B

dsh-bg-atelier

Bg Atelier

DSH Desktop Background Workshop: static backgrounds, Wallpaper Engine live scenes and mouse parallax, scene properties and presets, glass card faces, and dialogue effects.

The plugin will be installed here. Keep web if you are unsure.

npx -y @deepseek-ai/dsh plugin --profile web add github:Raylen-berry/dsh-desktop-wallpaper#0b81b0c423f9174329e574a0fbd91d6a5ee18506
READMECompatibilityVersions

Compatibility and provenance

Bg Atelier is published as dsh-bg-atelier and currently resolves to version 1.15.2. The Hub verifies its manifest and preserves the exact installation source for reproducible installs.

DSH compatibility
*
Runtime surfaces
web
Release source
github
Registry updated
9/28/2026

Versions

1.15.2stable
9/28/2026
1.15.0stable
9/28/2026
1.9.1stable
9/24/2026
Show 7 more versionsCollapse versions
1.7.0stable
9/22/2026
1.6.2stable
9/14/2026
1.6.1stable
9/13/2026
1.6.0stable
9/13/2026
1.5.5stable
9/12/2026
1.5.4stable
9/12/2026
1.4.1stable
9/11/2026

Related plugins

Loading related plugins…

Latest
1.15.2
DSH
*
HMR
Process restart
Tree shaking
Safe tree shaking not declared
Unpacked size
Unavailable
Files
Unavailable
Surface
web
License
MIT
Source
github
GitHub
★ 0
Weekly downloads
0
Last push
10/11/2026
View source ↗
README badge

Click the badge to copy Markdown for your README.

Do you maintain this Plugin?Claim benefit · Priority security scan

Verify the GitHub repository declared in package.json to manage this listing. After you claim it, Hub will prioritize a security scan of the current version and publish the result when it passes.

Claim this Plugin →
Report an issue

Related plugins

More verified plugins in ui-customization.

Web App@deepseek-ai/dsh-web-appThe dsh browser-surface bundle: the web patch layer over dsh-base plus the runtime glue plugin (frontend dist serving, web-surface prompt, bash runtime variables, URL line)Experimental Session Titles Bundle@deepseek-ai/dsh-experimental-session-titles-bundleRefresh session titles as new human prompts arrive.Personalized Recommendations@deepseek-ai/dsh-personalized-recommendationsPersonalized pages and built-in plugin recommendations offered as cards below answersWhale Widgetdsh-whale-widgetDeepSeek balance whale widget in the bottom-right corner of the DSH Web interface: balance/today’s usage/peak-off-peak pricing, customizable bubble click sequence (text/balance/today/peak-off-peak/image/random phrases and parallel weighted selection), per-line styles and fonts, floating quick editin

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 清单路由。