dsh-background-by-model 0.5.5 → 0.7.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.zh.md CHANGED
@@ -9,7 +9,7 @@
9
9
 
10
10
  > 派生自 [`Tkingxiao/dsh-any-background`](https://github.com/Tkingxiao/dsh-any-background),并重命名为 `dsh-background-by-model`。
11
11
 
12
- 一个 **DeepSeek Harness** 外观插件,核心是一份**有序的模型规则列表**:每条规则自带壁纸、主题色、布局模式、取景、透明度与模糊度,切换模型即切换背景。
12
+ 一个 **DeepSeek Harness** 外观插件,核心是一份**有序的模型规则列表**:每条规则自带壁纸(可多张,每张各有自己的取景与主题色)、布局模式、透明度与模糊度,切换模型即切换背景。
13
13
 
14
14
  > **v0.3.0 是破坏性更新**:视频背景、生成式背景与全局主题色均已被移除。详见 [CHANGELOG.zh.md 的 v0.3.0 条目](./CHANGELOG.zh.md#v030)。
15
15
 
@@ -76,19 +76,47 @@
76
76
 
77
77
  - **有序规则列表** — 可新增、删除、拖动排序并命名规则;每条规则用自己的匹配串参与匹配,先命中者生效,规则 1 兼任兜底。
78
78
  - **实时状态提示** — 「模型背景」页顶部会显示当前状态,例如「当前模型 deepseek-flash → 命中 · 规则 1」,方便当场验证规则写对没有;检测不到当前模型时会给出提示。
79
- - **外观随规则走** — 壁纸、主题色、布局模式、取景、透明度与模糊度都是每条规则自己的属性;除「界面」页外没有任何全局外观项。
80
- - **导入 / 导出** — 一键把**每一条规则连同它的图片**导出为 `dsh-background-by-model-theme.json`(版本 3,图片以 base64 内联),可随时导入还原。
79
+ - **外观随规则走,颜色随图走** — 壁纸(多张)、布局模式、透明度与模糊度是每条规则自己的属性;**取景和主题色则是每张图片自己的**。除「界面」页外没有任何全局外观项。
80
+ - **一条规则多张图** — 每条规则持有一组有序图片,用胶片条展示:可一次加多张(多选文件、拖放,或一行一个网址批量粘贴)、排序、把某张设为第一张、**原地替换某一张**(替换会保住它在轮换里的位置)、逐张删除。不轮换时规则画的就是**第一张**。删掉最后一张只是让这条规则变空,而空不等于失效:只要它还留着自己的主题色,它就照旧参与匹配与兜底、只给界面配色而不铺壁纸;连主题色也没有(比如刚新增的规则)才会被匹配跳过。空规则是一个看得见、退得回的状态,而不是卡住出不来的死胡同。一张图都没有时胶片条会隐藏、上方那块大预览**就是**上传按钮,所以添加图片的地方只有一个、也很显眼。
81
+ - **导入 / 导出** — 一键把**每一条规则连同它的全部图片**导出为 `dsh-background-by-model-theme.json`(版本 5,图片以 base64 内联),可随时导入还原。更早版本导出的文件同样能导入:规则唯一的那张图会被还原成它的图片列表,而在「主题色属于图片」之前写下的颜色会被抬升到每一张还没有自己颜色的图上——所以旧主题文件还原出来的观感与当初一模一样。
81
82
  - **文件持久化** — 所有设置与图片保存到文件系统 `~/.dsh/.dsh-background-by-model-data/`,不依赖 `localStorage`。
82
83
  - **自动迁移** — 旧版单壁纸配置在首次读取时自动升级,详见 [CHANGELOG.zh.md 的 v0.3.0 条目](./CHANGELOG.zh.md#v030)。
83
84
  - **中英双语** — 完整的中英文界面,自动跟随语言设置。
84
85
  - **主题守护** — 宿主重置主题后自动重新激活自定义主题。
85
86
 
87
+ ### 多图轮换
88
+
89
+ 按规则开关,且**默认关闭** —— 轮换是真要花流量、内存和电的,不该由默认值替你决定。
90
+
91
+ - **按规则开启** — 开关就在规则卡片里,规则至少有两张图之后才能打开。
92
+ - **每张停留** — 10 秒 / 30 秒 / 1 分钟 / 5 分钟 / 30 分钟 / 1 小时,也可以自己填秒数(限制在 5 秒 – 24 小时)。
93
+ - **换图顺序** — 「按顺序」自上而下走完一圈再回到第一张;「随机」会在**除当前这张之外**的所有图里等概率挑一张,因为抽到同一张看起来就跟这一次没生效一模一样。
94
+ - **切换模型时也换一张** — 可选的第二种触发方式:每次切换模型落到这条规则上就往前走一张。对「每次都想看到不一样」的规则来说,这就是全部功能,而且不用挂任何定时器。
95
+ - **只有正在生效的规则会轮换** — 全插件只有一个定时器,始终对准当前模型解析出的那条规则。标签页不可见时它会停下、回来时重新计时;只有一张图的规则(以及所有[节日](#节日特殊背景))从不排期。
96
+ - **下一张** — 立刻换一张,方便当场检查这组图。
97
+ - **跟着规则走的是外观,跟着图片走的是颜色** — 布局模式、透明度、模糊度留在规则上、原地不动;**主题色属于图片**,所以一组图可以依次是绿的、红的、以及跟随系统主题的,界面配色跟着壁纸一起换。过渡用的就是切换模型时那套交叉淡入。
98
+ - **取景是逐图的,颜色也是** — 构图和配色都属于某一张图:每张图各自保留自己的取景与主题色,同时共享规则的布局、透明度与模糊度。胶片条会标出哪些图已经各自有颜色,调色区上方也会写明当前编辑的是哪一张。
99
+ - **只加载用得到的图** — 启动时只读每条规则的**第一张**,其余的在展开卡片时、或者在轮换即将用到它时再读。所以「五条规则各十张图」不等于首帧之前先传五十张壁纸。
100
+
101
+ ### 节日特殊背景
102
+
103
+ 小小一个,不是一整块设置:**「配置」页上一个开关,别的什么都没有**。它默认就是开的;到了日子背景自己换,第二天早上自己换回。
104
+
105
+ - **行为** — 中秋与国庆当天,壁纸换成那个节日自己的图片,并配上该节日固定的主题色(中秋 `#384A77`、国庆 `#FFF6EB`);第二天交还给模型规则。这份配色同时写在节日条目和它的图片上——主题色现在住在图片里——所以以后节日也能多图轮换、每张带自己的配色。
106
+ - **中秋节** — 农历八月十五当天。它在公历上逐年移动(2024-09-17、2025-10-06、2026-09-25、2027-09-15……),所以是运行时按农历换算的,时区钉在 **Asia/Shanghai** —— 农历日期在北京时间午夜翻页,不是你那边的午夜。
107
+ - **国庆节** — 公历 10 月 1–7 日。
108
+ - **两者重叠时中秋优先** — 它们确实会撞(2025-10-06 就是同一天),一个精确的单日比七天窗口里的某一天更值得采信。
109
+ - **没有图的节日会回落到模型规则**,而不是把背景刷空。
110
+ - **内置壁纸** — 两个节日都自带一张压缩过的壁纸(原生分辨率下 228 KB 与 500 KB,原图共 8.37 MB)。只会去取**今天真能生效**的那一张,所以不在节日的配置一点都不会传。
111
+ - **图片和配色都不可替换,这是刻意的** — 一个要求用户去配置的彩蛋就不是彩蛋了。节日槽位是只读的:往 `modelbg-h-midautumn` / `modelbg-h-nationalday` 里放文件不会被任何一次读取采用,插件也拒绝写入、抓取和删除这两个槽位。主题色是节日定义里的常量、每次读取都强制覆盖——**节日条目和它的图片两处都覆盖**,所以手改 `theme-config.json` 里的 `color` 也换不掉节日配色。导出的主题文件只包含你自己的规则。
112
+ - **不想要它** — 关掉「配置」页那个开关,或者在同一个文件里写 `"holidays": { "enabled": false }`。
113
+
86
114
  ### 每条规则自带的外观
87
115
 
88
- - **背景图片** — 上传任意图片作为该规则的壁纸,每条规则一张独立图片文件。
89
- - **主题色** — HSL 色轮 + 数值输入 + 灵感色板,支持「从本图提取」与吸管「从图片取色」;不设主题色时跟随系统主题。实时生成整套 CSS 设计令牌。跟随系统主题时,界面配色交还宿主,而壁纸与「界面」页的透明度、模糊照旧生效——表面颜色是从宿主自己的令牌读出来后套上你的透明度的,所以壁纸不会被一块不透明底板盖住。
116
+ - **背景图片** — 一条规则可以放一张或多张图,每张图是独立文件。胶片条决定你正在编辑哪一张;不轮换时规则画的是**第一张**。规则也可以是**一张图都没有**的:这时它不再铺壁纸,但只要它有自己的主题色就照旧参与匹配与兜底(只是把界面按那个颜色配色),连主题色也没有才会被匹配跳过,直到你给它一点内容。
117
+ - **主题色** — HSL 色轮 + 数值输入 + 灵感色板,外加「从本图提取」和吸管「从图片取色」。**颜色属于图片**:这些控件编辑的是胶片条里选中的那张,胶片条上会标出哪些图已经各自有颜色,而没有自己颜色的图**跟随系统主题**、不会去继承规则的颜色。**一张图都没有**的规则只剩它自己的主题色可编辑——那正是这种规则唯一能画的东西。实时生成整套 CSS 设计令牌。跟随系统主题时,界面配色交还宿主,而壁纸与「界面」页的透明度、模糊照旧生效——表面颜色是从宿主自己的令牌读出来后套上你的透明度的,所以壁纸不会被一块不透明底板盖住。
90
118
  - **布局模式** — 适应 / 填充 / 拉伸 / 平铺 / 居中。
91
- - **取景** — 在视口比例的编辑器中拖动平移、滚轮缩放;**仅「适应」模式下可编辑**,提交的构图在窗口缩放、跨屏移动后保持一致。
119
+ - **取景** — 在视口比例的编辑器中拖动平移、滚轮缩放;**仅「适应」模式下可编辑**,提交的构图在窗口缩放、跨屏移动后保持一致。按图分别保存。
92
120
  - **背景透明度** — `0–100%`,作用于该规则的壁纸层。
93
121
  - **背景模糊** — `0–60 px`,作用于壁纸层。
94
122
 
@@ -106,8 +134,8 @@
106
134
  | 选项卡 | 作用范围 | 内容 |
107
135
  | --- | --- | --- |
108
136
  | **界面** | 全局,所有模型共用 | 主背景、左侧栏、右侧栏、卡片面板、输入框与控件、设置面板、对话文本框、轨迹页的透明度与模糊度 |
109
- | **模型背景** | 每条规则 | 有序规则列表、顶部实时状态,以及每条规则的壁纸、主题色、布局模式、取景、透明度与模糊度 |
110
- | **配置** | — | 导入 / 导出整套规则(`dsh-background-by-model-theme.json`) |
137
+ | **模型背景** | 每条规则 | 有序规则列表、顶部实时状态,以及每条规则的图片(胶片条)、**逐图主题色**、布局模式、逐图取景、透明度、模糊度与[多图轮换](#多图轮换) |
138
+ | **配置** | — | 导入 / 导出整套规则(`dsh-background-by-model-theme.json`),外加[节日特殊背景](#节日特殊背景)那一个开关 |
111
139
 
112
140
  原先的 **「色彩」** 选项卡已删除——主题色改为每条规则自己的属性;原 **「背景」** 选项卡已改造成 **「模型背景」**。
113
141
 
@@ -117,8 +145,9 @@
117
145
 
118
146
  | 文件 | 内容 |
119
147
  | --- | --- |
120
- | `theme-config.json` | 规则列表 + 全局「界面」设置 |
121
- | `modelbg-<slot>` | 每条规则的图片,保存为原始字节,无扩展名 |
148
+ | `theme-config.json` | 规则列表(每条规则含图片列表与轮换设置)+ 全局「界面」设置 + 节日覆盖配置 |
149
+ | `modelbg-<slot>` | 一张图片,保存为原始字节,无扩展名 —— 一张图一个文件,所以一条有三张图的规则占三个槽位 |
150
+ | `modelbg-h-midautumn` / `modelbg-h-nationalday` | 不使用:两张节日壁纸都随包发布,直接从包内送出 |
122
151
 
123
152
  ## 安装
124
153
 
@@ -170,7 +199,13 @@ pnpm run typecheck
170
199
 
171
200
  改完 `src/` 必须重新执行 `pnpm run bundle` 才会生效——挂载的 profile 加载的是 `lib/`。
172
201
 
173
- `pnpm test` 会构建并做类型检查(`tsdown && tsc -p tsconfig.json`)。
202
+ `pnpm test` 会构建、类型检查并跑五道校验(`tsdown && tsc -p tsconfig.json && node scripts/holiday-check.ts && node scripts/rotation-check.ts && node scripts/repaint-check.ts && node scripts/ui-strings-check.ts && node scripts/node-half-check.mjs`)。五道都不需要依赖、不需要转译器、也不需要浏览器,也可以单独跑:`pnpm check:holiday` / `pnpm check:rotation` / `pnpm check:repaint` / `pnpm check:ui` / `pnpm check:node`。
203
+
204
+ - **`check:holiday`** — 两个节日窗口对照已知日期、北京时间的跨日边界(23:59 与 00:01)、1900–2100 年间的闰八月,以及 `pickHoliday` 允许节日接管背景之前必须通过的四道闸门。
205
+ - **`check:rotation`** — 轮换的判定(`nextIndex` / `isRotating`):不会走越界、随机不会重复当前这张(在整个随机取值范围内穷举)、也不会把只有一张图的规则报成「正在轮换」。
206
+ - **`check:repaint`** — 「这次编辑要不要重画界面」的判定(`shouldRepaint`),其中就包含实际踩过的那个坑:**这次编辑本身**制造出了生效规则(某条规则的第一张图、第一个颜色或自动提取出的颜色)时,即使被编辑的规则此刻还不是生效规则,也必须立刻重画。它同时还会在 `src/client/index.tsx` 里任何一条写入路径不再询问这个判定时报错——也就是说,把老的 `id === activeRuleId` 判断写回去,会是构建校验失败,而不是你下一次上传时界面不动;轮换步骤不再重发调色板(主题色属于图片,换图就是换配色)同样会被它拦下。
207
+ - **`check:ui`** — 每个 `t('…')` 键在中英两本字典里都存在、两本字典键集完全一致、每个 `dab-…` 类在样式表里都有规则,且没有字典条目变成没人引用的死键。
208
+ - **`check:node`** — 把构建好的 node 半边通过它真实的 RPC 处理器跑一遍,`DSH_HOME` 指向临时目录:节日配置块穿过共享的 sanitizer、内置壁纸从空槽位被送出(且不会因此写进数据目录)、节日槽位拒绝写入 / 删除 / 抓取而丢进去的文件被忽略、普通规则槽位照常写入和删除,以及手改过的配置无法把节日指向别的规则的图片。它还覆盖逐图主题色这套形状:读取时抬升的两个方向(缺键继承规则色、显式 `null` 不继承)、颜色经过文件往返后各自独立,以及 `null` 是写出键而不是省略。
174
209
 
175
210
  ## 常见问题
176
211
 
@@ -181,7 +216,25 @@ pnpm run typecheck
181
216
  匹配是先命中者胜,而不是最精确者胜。把更具体的规则往上拖,或调整顺序让你想要的规则排在前面。
182
217
 
183
218
  **图片存在哪?**
184
- 在 `~/.dsh/.dsh-background-by-model-data/`:每条规则一个 `modelbg-<slot>` 文件,外加 `theme-config.json`。
219
+ 在 `~/.dsh/.dsh-background-by-model-data/`:每张图一个 `modelbg-<slot>` 文件,外加 `theme-config.json`。
220
+
221
+ **我开了轮换,背景却一直没变。**
222
+ 有三件事会拦住它:规则至少要有两张图;标签页必须可见(隐藏的标签页什么都不画,轮换跟着一起停);只有当前模型解析出的那条规则在轮换——没生效的规则,「下一张」按钮就是灰的,正是这个原因。
223
+
224
+ **轮换有代价吗?**
225
+ 有,所以默认关闭。每张图都按原始保真度保存(不做重编码),所以一条放了十张 8 MB 壁纸的规则就是十份 8 MB;每次换图还会重画整个界面。建议一组控制在两到五张、节奏也别太密。启动时只读每条规则的第一张,轮换也会提前预热它下一张要用的图,所以代价落在内存和磁盘上,而不是启动时间上。
226
+
227
+ **删掉规则里的图片之后,主题色为什么不起作用了?**
228
+ 这是已经修掉的旧行为,根因是「有没有图」被当成了「这条规则是否可用」:图片删光的规则不再参与匹配,效果自然也就无从谈起,而它原本负责的模型还会被交给下一条规则。现在只要规则**有图、或者有自己的主题色**就仍然生效:不铺壁纸,只按这个颜色给界面配色(面板上会写明当前属于哪种状态)。连主题色也没有、也就是一点内容都没有的规则才会被跳过——「这条规则还没有图片,也没有自己的主题色:没有可显示的内容,匹配和兜底都会跳过它」。
229
+
230
+ **我更新了插件,面板说我的改动没有保存。**
231
+ 浏览器半边和宿主半边是分开加载的:刷新页面后新客户端可能已经生效,而 DSH 主进程还在跑上一个版本的插件——它读不懂新的配置格式(`SCHEMA_VERSION` 比它低就知道),下一次写入就可能把规则丢掉。客户端检测到这种情况会**扣住所有配置写入**并提示你:重启 DSH 之后,多图配置、轮换设置等一切都会正常保存。
232
+
233
+ **我给一张图设了颜色,其它图片却没跟着变。**
234
+ 这是设计如此:从 0.7.1 起主题色属于**图片**而不是规则,所以一组图可以依次是不同调性(绿的、红的、以及跟随系统主题的)。调色控件作用于胶片条里选中的那一张,控件上方的提示会写明是哪一张。唯一例外是**一张图都没有**的规则:那时控件编辑的是规则自己的主题色——那正是这种规则能画的东西,而且它刻意不作为该规则图片的默认值。
235
+
236
+ **更新之前我设的主题色去哪了?**
237
+ 哪儿也没去:在「逐图主题色」之前写下的图片条目**根本没有** `color` 这个键,而这正是加载时用来区分「从来没有自己的颜色」和「被主动清空过」的依据——前者会把规则的颜色抬升到每一张这样的图上。所以带主题色的规则升级后观感完全一致,此后每张图就可以各自改色了。
185
238
 
186
239
  **能分享整套配置吗?**
187
240
  可以,在 **「配置」** 页导出即可;导出的 JSON 会把每条规则的图片内联进去。
@@ -200,18 +253,33 @@ pnpm run typecheck
200
253
 
201
254
  ## 近期优化
202
255
 
203
- > 这里只列最近两个版本;更早的版本(v0.5.0 及以前)见 [CHANGELOG.zh.md](./CHANGELOG.zh.md)。
204
-
205
- ### v0.5.5
206
-
207
- - **颜色预览块把色值打在自己身上** — 它位于 H/S/L(R/G/B)那一列的底部,边框同样是 1px,却一个字都没有,于是颜色一浅(报告里是 `#BADEE8`,L 82%)就读成第四个空白输入框,而它没有任何可输入的内容。现在把 `#RRGGBB` 用等宽字体居中打在颜色上,字色按 **Rec.709 亮度**(壁纸取色用的同一个公式)选取,值不会消失在自己的底色里;那个它从未兑现的 `scale(1.02)` hover 也去掉了。HSL/RGB 切换器上方重复的那行色值一并删除。
208
- - **清空颜色的按钮改成说它做什么** — **「系统主题」**(一个状态)现在是**「跟随系统主题」**(那个动作),并带上宿主自己的太阳字形。它与 0.5.3 把无颜色按钮改成**「自定义颜色」**的那次是同一种修正的两侧。
209
-
210
- ### v0.5.4
211
-
212
- - **填充上的文字改读宿主的「色块墨色」,不再用 `brand-text`** — 跟随系统主题时,布局模式的选中胶囊、「+ 新增规则」按钮和设置页的品牌方块,底色取自宿主自己的 `--dsw-alias-brand-primary`,而它**不是品牌色、是对比墨色**:宿主浅色档近黑(`#0f1115`),深色档近白(`#f9fafb`)。它们的文字读的是 `--dsw-alias-brand-text`,而宿主在两档里都把它定义成与底色**完全相同**的值、自己的 CSS 从不使用。于是在深色系统上就成了有底色却没有文字的方块 —— 白底主按钮、白底选中胶囊、白底图标块(实测正好 `#f9fafb`),只有插件自己持有一套调色板时才看得见。四处现在统一读 `--dsw-alias-label-primary-inverted`,也就是宿主自己画在品牌/对比色块上的墨色:浅色档 `#fff`,深色档 `#353638`。
213
- - **开关打开态的圆点是同一个毛病的小号版本** — 硬编码 `#fff` 画在 `--dsw-alias-brand-primary` 轨道上,而深色档那条轨道本身就是白的。
214
- - **插件自建的深色调色板是同一问题的镜像** — 那一档的品牌填充故意保持 50% 以上亮度,而**宿主自己的主按钮**用来写标签的 `--dsw-alias-label-primary-foreground`(画在 `--dsw-alias-button-primary-fill` 上)被写死成白色。现在它随填充亮度翻转(与 `brand-text` 共用一条判定),浅色分支也补上了 `label-primary-inverted`,让插件的调色板自己成对,而不是继承宿主当前恰好所处的档位。
256
+ > 这里只列最近两个版本;更早的版本(v0.6.0 及以前)见 [CHANGELOG.zh.md](./CHANGELOG.zh.md)。
257
+
258
+ ### v0.7.1
259
+
260
+ - **主题色下放到图片** — 一条规则是一组图片的轮换,而这些图往往是为不同心情收的,不该共用同一个强调色。每张图现在带自己的 `color`,色轮、数值输入、灵感色板、「从本图提取」、吸管和「跟随系统主题」全都作用于**胶片条里选中的那张**。控件上方写明当前作用于哪张图,胶片条也标出哪些图已经各自有颜色,所以「我改了却没反应」不会是这个功能教给你的第一件事。
261
+ - **规则自己的颜色只剩一个含义** — **一张图都没有时它画什么**。它不是该规则图片的默认值:没有自己颜色的图**跟随系统主题**,而不是去继承规则色——正是这一点才让「绿的、红的、跟随系统」这样一组轮换成立。所以清空某张图的颜色只影响那一张,而规则色会留在「只剩它能画」的那个状态里等着。
262
+ - **升级不会丢主题色** — 这个版本之前写下的图片条目**根本没有** `color` 键,而这个区别正是加载器的全部依据:缺键 = 「从来没有自己的颜色」,于是规则色被抬升到它身上(只做一次,且在共享 sanitizer 里做,两半边行为一致);显式的 `null` = 「主动清空过」,原样保留。规则自身也留着那个颜色,所以把有主题色的规则清空后它照样能画。
263
+ - **轮换每一步都会重发调色板,这不是细节** — 换图原本只重画壁纸,于是「逐图主题色」会等到**别的**事情顺手重跑一次 apply 才出现:拖动调色盘,或切换模型。这正是这个插件已经踩过一次的现象(「更新的不太及时,只有我动调色盘或者切模型的时候才出现」),所以调色板的施加被收成一个函数,模型切换和轮换的每一步(定时器与手动「下一张」共用一个出口)都走它。
264
+ - **节日配色同样逐图** — 节日的固定配色同时写在节日条目和它的图片上、每次读取都由定义强制覆盖,于是「节日多图轮换、每张带自己的配色」只需要改 `HOLIDAYS` 和它的素材,而不需要在渲染层再开一条代码路径。
265
+ - **没有图片的规则只剩一个上传入口** — 上方那块大预览**本身就是按钮**了(点它上传,也可以把文件拖上去),而胶片条在一张图都没有时**完全不渲染**:它里面除了一块「添加图片」再没有别的东西,而胶片条是一组图片的列表,一张图都没有的状态下它没有存在的理由。其它都没动:带文字的 **添加图片** / **从网址** 按钮还在原位;有图片时预览依旧刻意保持惰性(拖到胶片条是新增,「替换这张」仍是显式的带文字按钮——正是这一点让预览不会吞掉用户无意的点击)。
266
+ - **配置格式升到 4,旧宿主依旧吃不掉配置** — `images[].color` 对 schema 3 的 sanitizer 是未知字段,而它会**按自己认识的键重建**每个图片条目:颜色会一直在内存里活到下一次重新加载,然后悄无声息地消失,日志里还什么都不会说。版本判断是简单的 `>=`,所以报出更低版本的宿主会让所有写入被扣住、面板里说明,直到重启 DSH。
267
+ - **门禁覆盖到它** — `check:node` 现在双向钉住抬升(缺键继承规则色、显式 `null` 不继承)、逐图颜色经过文件往返后各自独立、节日两处颜色都被强制,以及 `null` 是**写出键**而不是省略键(写成省略就是每次加载都悄悄把规则色继承回来)。`check:repaint` 还会在轮换步骤不再重发调色板时报错。
268
+
269
+ ### v0.7.0
270
+
271
+ - **每条规则多图轮换** — 规则现在持有一组有序图片,可以按自己的节奏循环:10 秒 / 30 秒 / 1 分钟 / 5 分钟 / 30 分钟 / 1 小时,或自定义停留时长;顺序可选**按顺序**或**随机**(随机绝不会抽到当前正在显示的那张,因为那看起来就跟这一次没生效完全一样)。默认关闭 —— 轮换真的要花流量、内存和电,不该由默认值替你决定。
272
+ - **第二种触发:切换模型** — 打开「切换模型时也换一张」之后,换图就与时间无关了:每次切换模型落到这条规则上,就显示它的下一张。这样一条规则可以是「每次都不一样」,而完全不需要挂定时器。
273
+ - **只有一个定时器,且始终对准生效规则** — 它的重排条件是「排期真正依赖的那些输入」(规则、间隔、顺序、图片数量、标签页可见性)组成的签名,所以拖动滑块导致每秒重跑几十次 apply 也不会把停留计时反复清零;标签页隐藏时轮换直接停下,而不是对着空屏画三次。
274
+ - **换的只有图本身** — 主题色、布局模式、透明度、模糊度都留在规则上;只有画面在变,用的就是切换模型时那套交叉淡入。还能单独设淡入时长(0 就是硬切)。
275
+ - **是分镜条,不是表单** — 规则卡里那张单图缩略图变成了胶片条:可一次加多张(多选、拖放、一行一个网址)、点选要编辑的那张、排序、设为第一张、原地替换、删除。上方大预览显示选中的那张,正在显示的那张带一个跳动的圆点。
276
+ - **空规则是一个状态,不是死路** — 这个功能的第一版拒绝删除最后一张,转而「清空它的字节」,结果把条目本身留了下来:胶片条第 1 位一块永远删不掉的空白图,于是下一次上传只能排到第 2 位,规则继续什么都不画、预览一直停在空帧。现在删除最后一张就是把列表清空;新建规则从空列表开始(第一张图到达时才分配槽位);你加进去的那张就是你正在看的那张;手改导致「每一项都不可用」的列表也落到这个状态,而不是被硬塞回一个坏槽位。
277
+ - **空规则不等于失效:主题色继续生效** — 第一版把「有没有图」当成了「这条规则是否可用」,于是把图片删光的规则**既不再匹配、也不再当兜底**:它自己那份主题色、色轮、灵感色板、「跟随系统主题」全部变成摆设(现象就是「主题色无效」),而它原本负责的模型被悄悄交给下一条规则。现在只要是**有图、或者有自己的主题色**(`ruleCanPaint`)就仍然生效 —— 不铺壁纸,只给界面配色。面板上的说明也按三种真实状态分开说(无图有颜色 / 无图无颜色 / 有图但还没取到内容),不再拿同一句话覆盖三种情况。
278
+ - **改一条没在生效的规则也会立刻生效** — `color` / `enabled` / `match` 都影响「哪条规则赢」,但以前只有编辑当前生效规则时才会重新解析:给空规则选上第一个颜色、或往一条还没赢的规则里输入匹配串,界面上都不会有反应,要等某个无关事件顺手重跑一次解析。
279
+ - **只加载用得到的图** — 启动时只灌每条规则的**第一张**(跟多图出现之前每条规则灌一张完全一致),其余的在展开卡片时、或轮换即将用到时再取。于是「五条规则二十张图」不等于首帧之前先传二十张全尺寸 data URL。
280
+ - **旧宿主再也不可能吃掉一份配置** — node 半边现在会公布自己写入的配置格式,客户端发现宿主报出的版本低于自己(`SCHEMA_VERSION`,2 → 3 起表示「空图片列表合法」)时会**扣住所有配置写入**并在面板里说明。没有这道闸门,更新包之后只刷新一次页面,上一个版本的 sanitizer 就会在下一次拖动滑块时把全部规则丢掉。
281
+ - **老配置照常读,老导出照常导入** — 规则里那对单图字段(`slot` / `bgState`)会在读取时被提升成 `images: [{ slot, bgState }]`;主题文件升到版本 4(版本 3 及更早仍可导入),导出与还原的是每条规则的全部图片,而不只是第一张。
282
+ - **第四道静态门禁:`pnpm check:rotation`** — 轮换的判定是纯函数(`nextIndex` / `isRotating`),现在被钉住了:不会走越界、随机不会重复当前这张(在整个随机取值范围内穷举,不是抽一次样本)、也不会把只有一张图的规则报成「正在轮换」。`check:node` 则通过真实 RPC 处理器覆盖新形状:旧配置提升、逐图取景、去重、钳位、嵌套字段漂移告警,以及各图槽位互不干扰。
215
283
 
216
284
  ## Star History
217
285
 
Binary file
Binary file