dsh-background-by-model 0.12.0 → 0.12.2
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/CHANGELOG.md +15 -1
- package/CHANGELOG.zh.md +15 -1
- package/README.md +9 -29
- package/README.zh.md +9 -29
- package/icon.svg +15 -0
- package/lib/client.js +30 -0
- package/locale/en.json +6 -0
- package/locale/zh.json +6 -0
- package/package.json +8 -3
package/CHANGELOG.md
CHANGED
|
@@ -1,6 +1,20 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
-
> The full release history lives here; the **Recent optimizations** section of [README.md](./README.md#recent-optimizations) lists only the two most recent releases (v0.12.
|
|
3
|
+
> The full release history lives here; the **Recent optimizations** section of [README.md](./README.md#recent-optimizations) lists only the two most recent releases (v0.12.2 / v0.12.1).
|
|
4
|
+
|
|
5
|
+
## v0.12.2
|
|
6
|
+
|
|
7
|
+
- **The plugin manager no longer shows a package name and a generic icon** — `locale/en.json` and `locale/zh.json` supply the title and description the manager displays, and `icon.svg` replaces the default artwork.
|
|
8
|
+
- **Both files are EXPORTED, and that is what makes them readable** — the reader resolves them through Node's ESM resolver, so `exports` must name `./locale/*.json`; a file on disk without that entry resolves to nothing and is treated as absent, with no error anywhere.
|
|
9
|
+
- **And they are in `files`** — everything above can be right in the repository and still be missing from the tarball, which looks exactly the same in the UI.
|
|
10
|
+
- **`check:meta`** — asserts all of it, then asks `readPluginMeta` itself for the answer the card would show. Verified to fail when the `exports` entry, the `files` entry or the `icon` key is removed.
|
|
11
|
+
- **The publish gate accepts globs in `files`** — it compared every `files` entry with `packed.includes()`, so `locale/*.json` looked like a missing literal filename and the pack step refused a perfectly good tarball. A literal path is still matched by name; a glob now has to match at least one packed file.
|
|
12
|
+
|
|
13
|
+
## v0.12.1
|
|
14
|
+
|
|
15
|
+
- **Fix: "a picture the agent added has no theme colour"** — the auto-extract was hooked to the panel's own three upload paths, and the agent's `add_image` reaches this half by none of them: the node half downloads and writes the config, and the browser half only ever adopts a newer revision. Both adoption sites (the 3 s poll and the refused-write handler) now theme the slots that were not there before the adopt.
|
|
16
|
+
- **The trigger is the slot set, not `color === null`** — null is also what the clear button stores, so re-theming on it would refill a colour the user deliberately removed.
|
|
17
|
+
- **`check:repaint` pins both adoption sites** — each must sample the slot set BEFORE `adoptConfig`, and the call is matched to its own site, so dropping one of the two puts the bug back through the adjacent door.
|
|
4
18
|
|
|
5
19
|
## v0.12.0
|
|
6
20
|
|
package/CHANGELOG.zh.md
CHANGED
|
@@ -1,6 +1,20 @@
|
|
|
1
1
|
# 更新日志
|
|
2
2
|
|
|
3
|
-
> 这里保留完整的历史记录;[README.zh.md](./README.zh.md#近期优化) 的「近期优化」一节只列最近两个版本(v0.12.
|
|
3
|
+
> 这里保留完整的历史记录;[README.zh.md](./README.zh.md#近期优化) 的「近期优化」一节只列最近两个版本(v0.12.2 / v0.12.1)。
|
|
4
|
+
|
|
5
|
+
## v0.12.2
|
|
6
|
+
|
|
7
|
+
- **插件管理器里不再是包名加通用图标** —— `locale/en.json` 与 `locale/zh.json` 提供管理器显示的标题与描述,`icon.svg` 顶掉默认图标。
|
|
8
|
+
- **两份文件必须写进 `exports`,否则读不到** —— 读取方走 Node 的 ESM 解析器,`exports` 要声明 `./locale/*.json`;磁盘上有但这里没写就解析不到,会被当成不存在,且不报任何错。
|
|
9
|
+
- **还要写进 `files`** —— 上面全对、包里却没有,界面上看起来一模一样。
|
|
10
|
+
- **`check:meta`** —— 把这些都断言一遍,最后直接问 `readPluginMeta` 卡片上会显示什么。撤掉 `exports`、`files` 或 `icon` 任意一项都验证过会红。
|
|
11
|
+
- **发布闸门支持 `files` 里的通配符** —— 它原来用 `packed.includes()` 比对每一项,于是 `locale/*.json` 被当成一个不存在的字面文件名,一个完全正常的包被打包步骤拒绝。现在字面路径仍按名比对,通配符则要求至少匹配到包里的一个文件。
|
|
12
|
+
|
|
13
|
+
## v0.12.1
|
|
14
|
+
|
|
15
|
+
- **修掉"AI 加的图片没有主题色"** —— 自动取色原来只挂在面板自己的三条上传路径上,而 AI 的 `add_image` 一条都不走:node 半边下载并写配置,浏览器半边只能接盘一个新版本号。现在两处接盘(3 秒轮询与陈旧写入处理器)都会给"接盘前不存在的槽位"取色。
|
|
16
|
+
- **判据是槽位集合,不是 `color === null`** —— `null` 同时也是「清除颜色」按钮存的值,拿它当"没提取过"会把用户故意清掉的颜色填回来。
|
|
17
|
+
- **`check:repaint` 钉住两处接盘** —— 各自必须在 `adoptConfig` **之前**采样槽位集合,且调用要对得上自己那一处;少一处就是从这个 bug 隔壁那扇门把它放回来。
|
|
4
18
|
|
|
5
19
|
## v0.12.0
|
|
6
20
|
|
package/README.md
CHANGED
|
@@ -237,7 +237,7 @@ To mount a working copy into a profile instead, add it to the profile's `package
|
|
|
237
237
|
|
|
238
238
|
After changing anything under `src/`, run `pnpm run bundle` again — the mounted profile loads `lib/`, so edits do not take effect until the bundle is rebuilt.
|
|
239
239
|
|
|
240
|
-
`pnpm test` builds, typechecks and runs
|
|
240
|
+
`pnpm test` builds, typechecks and runs sixteen checks, none of which needs a dependency, a transformer or a browser. Each can also be run on its own with `pnpm check:holiday` / `pnpm check:rotation` / `pnpm check:transition` / `pnpm check:repaint` / `pnpm check:code-plate` / `pnpm check:image-mode` / `pnpm check:rules` / `pnpm check:preset` / `pnpm check:ui` / `pnpm check:watchdogs` / `pnpm check:scheme` / `pnpm check:store` / `pnpm check:agent` / `pnpm check:rev` / `pnpm check:meta` / `pnpm check:node`:
|
|
241
241
|
|
|
242
242
|
- **`check:holiday`** — the two holiday windows, the Beijing day boundary, leap eighth months across 1900–2100, and the four gates `pickHoliday` applies.
|
|
243
243
|
- **`check:rotation`** — `nextIndex` / `isRotating`: no walking off the end, shuffle never repeating the image on screen, and nothing called "rotating" with nothing to rotate.
|
|
@@ -253,6 +253,7 @@ After changing anything under `src/`, run `pnpm run bundle` again — the mounte
|
|
|
253
253
|
- **`check:store`** — the two decisions behind the storage cleanup, `referencedSlots` and `orphanSlots`: a picture in use is never an orphan, a stray holiday-slot file always is, and the browser half sends RULE slots rather than the whole config.
|
|
254
254
|
- **`check:agent`** — agent access and the config revision: off by default, only an explicit `true` granting it (`'yes'` / `1` / `null` do not), the recommended profile not turning it on, an export not carrying it, the revision only ever moving forward, and a config written before either field reading as revision 0.
|
|
255
255
|
- **`check:rev`** — the panel's revision chain: a write carries `expectedRev`, a successful one records the host's answer, `setRev` mutates the live object, an import neither zeroes the revision nor reads it after the wipe, installing the recommended profile goes through one `adoptRecommended` call rather than a `resetStore` plus a write, config writes are chained while picture bytes are released only after the config lands (imports included), a tool-added picture derives a slot name from the clock, and two callers cannot adopt at once. Miss any link and the next save refuses itself, so an edit visibly undoes itself ("click + once, the card flashes and disappears").
|
|
256
|
+
- **`check:meta`** — how the plugin describes ITSELF in the plugin manager and the settings pages: `locale/<language>.json` carrying a title and a description per language, both files EXPORTED (the reader resolves them through Node's ESM resolver, so a file on disk that `exports` does not name resolves to nothing and is silently treated as absent), both listed in `files` (or the published tarball is missing them and looks identical), and an icon that is a relative path, inside the package, SVG/PNG/JPEG/WebP under 256 KiB, with a 36×36 viewBox and nothing referenced externally. When the harness is installed next door it ends by asking `readPluginMeta` itself, because the fallback it otherwise answers with — the bare package name — is exactly what a reader sees on the card.
|
|
256
257
|
- **`check:node`** — the built node half through its real RPC handler with `DSH_HOME` redirected and `fetch` stubbed: the holiday block, the festival art's content-hash cache and its pruning, fallback across the three edges, the per-image color AND effect lifts, the global switch effect, the atomic config write with its backup and its recovery, the store's usage report and cleanup, and the recommended profile's seven pictures end to end (including the old manifest method being gone, the slot whitelist, and the retry budget).
|
|
257
258
|
|
|
258
259
|
## FAQ
|
|
@@ -309,34 +310,13 @@ The effect is **Instant**, or the duration is `0` — an effect and a duration a
|
|
|
309
310
|
|
|
310
311
|
> Only the two most recent releases are listed here; older ones live in [CHANGELOG.md](./CHANGELOG.md).
|
|
311
312
|
|
|
312
|
-
### v0.12.
|
|
313
|
-
|
|
314
|
-
- **The
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
- **
|
|
319
|
-
- **The panel checks the revision every 3 s**, so an agent's edit repaints without a reload — a no-op while access is off.
|
|
320
|
-
- **`SCHEMA_VERSION` is 11**, with a new `check:agent` and the stale-write and access round trips added to `check:node`.
|
|
321
|
-
|
|
322
|
-
### v0.11.0
|
|
323
|
-
|
|
324
|
-
- **The download source moves to Bilibili's image CDN** — the recommended profile's seven wallpapers and both holiday pictures now come from `i0`/`i1`/`i2.hdslb.com`, three edges falling back to each other; the three screenshots in this README stay where they are, since they play no part at runtime.
|
|
325
|
-
- **The recommended profile's rules ship inside the plugin** — seven model rules and their interface numbers are compiled into the bundle, and the button downloads only the seven pictures. It no longer needs GitHub to be reachable, and there is no "the remote profile is newer than this build" gate left, nor a `preset.json` manifest — what gets installed is always what this build itself writes.
|
|
326
|
-
- **The request set is a constant table** — slot → BFS path, fixed at build time, and a BFS path is a hash of the upload. So a wallpaper URL is immutable in a way a git tag is not.
|
|
327
|
-
- **The addresses carry `@3840w.webp`** — the uploads are 2.4–12 MB PNGs (76 MB for the set); with that suffix they are the 250–365 KB 4K WebPs whose sha1 matches what is already in a data directory.
|
|
328
|
-
- **The festival cache is keyed by content hash** — `holiday-cache/<tag>/` became `holiday-cache/<first eight of the hash>/`. New art means a new address, therefore a new directory and a guaranteed re-download; the "remember to bump the version too" trap is gone, and the old tag directories are taken by the same sweep once the new art lands.
|
|
329
|
-
- **`SCHEMA_VERSION` stays 10** — nothing entered or left the config shape: what changed is where those numbers come from, not what they look like.
|
|
330
|
-
- **Checks** — `check:preset` now pins the built-in profile itself (rule order, the slot ↔ URL table, the webp transform and content hash in each address, the cache generation); `check:node` rewrites the holiday and profile sections (three-edge fallback and the retry budget, the old `fetchPresetConfig` method being gone, the slot whitelist, tag directories being swept); section 3 of `check:scheme` no longer reaches the network.
|
|
331
|
-
|
|
332
|
-
### v0.10.0
|
|
333
|
-
|
|
334
|
-
- **The config is written atomically, with a `.bak` of the last good file** — a save writes a temp file and renames it over the live one, keeping the previous parseable file as the backup; a corrupt live file is restored from it instead of falling back to the factory defaults and then being overwritten by your next drag.
|
|
335
|
-
- **Opacity, brightness and blur are saved per image** — the same layer as the layout mode, framing and theme color; a schema-9 config's rule-level values are lifted onto every image on read, so nothing changes on screen.
|
|
336
|
-
- **`SCHEMA_VERSION` is 10** — the fields moved, and an older host would drop them in silence, so the browser half has to know.
|
|
337
|
-
- **A blurred wallpaper no longer paints a dark rim around the viewport** — the layer's box is grown 2σ past the screen edge and clipped, with the framing moved back by the same amount, so the blur samples off screen instead of fading into the page behind it.
|
|
338
|
-
- **A switch between two different opacity, brightness or blur values animates now** — each layer keeps its own picture's filter, and the wallpaper's opacity rides the transition instead of snapping.
|
|
339
|
-
- **Dragging one of the three sliders no longer repaints everything per frame** — a drag frame writes only that field's property, and one full repaint lands when the gesture ends.
|
|
313
|
+
### v0.12.2
|
|
314
|
+
|
|
315
|
+
- **The plugin manager and the settings pages describe this plugin properly** — `locale/en.json` and `locale/zh.json` carry its title and description in each language, and `icon.svg` (36×36, the same viewBox the built-in artwork uses) replaces the generic package glyph. Both are listed in `exports` and in `files`: the reader resolves them through Node's ESM resolver, so a locale file on disk that `exports` does not name resolves to nothing, and a file outside `files` is missing from the published tarball — both look exactly like "no locale at all" in the UI, with no error anywhere. `check:meta` pins the lot and ends by asking `readPluginMeta` itself what the card would show. The publish gate now accepts globs in `files`, so a `locale/*.json` entry no longer reads as a missing literal filename.
|
|
316
|
+
|
|
317
|
+
### v0.12.1
|
|
318
|
+
|
|
319
|
+
- **Fix: a picture the agent added had no theme colour** — the automatic extraction was hooked to the panel's own upload paths, and the agent's `add_image` reaches this half by none of them: the node half downloads and writes the config, and the browser half only adopts a newer revision. Both adoption sites now theme the slots that were not there before, so a picture added by the agent is themed like one added by hand, and the tools' own descriptions are finally true.
|
|
340
320
|
|
|
341
321
|
## Star History
|
|
342
322
|
[](https://www.star-history.com/?repos=HarmlessFunny%2Fdsh-background-by-model&type=timeline&legend=bottom-right)
|
package/README.zh.md
CHANGED
|
@@ -237,7 +237,7 @@ pnpm test # 构建 lib/、类型检查、跑十三道检查
|
|
|
237
237
|
|
|
238
238
|
改完 `src/` 必须重新执行 `pnpm run bundle` 才会生效 —— 挂载的 profile 加载的是 `lib/`。
|
|
239
239
|
|
|
240
|
-
`pnpm test`
|
|
240
|
+
`pnpm test` 会构建、类型检查并跑十六道校验,十六道都不需要依赖、不需要转译器、也不需要浏览器。也可以单独跑:`pnpm check:holiday` / `pnpm check:rotation` / `pnpm check:transition` / `pnpm check:repaint` / `pnpm check:code-plate` / `pnpm check:image-mode` / `pnpm check:rules` / `pnpm check:preset` / `pnpm check:ui` / `pnpm check:watchdogs` / `pnpm check:scheme` / `pnpm check:store` / `pnpm check:agent` / `pnpm check:rev` / `pnpm check:meta` / `pnpm check:node`:
|
|
241
241
|
|
|
242
242
|
- **`check:holiday`** —— 两个节日窗口、北京时间的跨日边界、1900–2100 年间的闰八月,以及 `pickHoliday` 的四道闸门。
|
|
243
243
|
- **`check:rotation`** —— `nextIndex` / `isRotating`:不走越界、随机不重复当前这张、没有可轮换的东西时绝不报「正在轮换」。
|
|
@@ -253,6 +253,7 @@ pnpm test # 构建 lib/、类型检查、跑十三道检查
|
|
|
253
253
|
- **`check:store`** —— 存储清理的两个判定:`referencedSlots` 与 `orphanSlots`。钉住「正在用的图不会被当成孤儿」与「节日槽位的文件必须可清」,外加浏览器半边传的是**规则槽位**而不是整份配置。
|
|
254
254
|
- **`check:agent`** —— AI 授权与配置版本号:默认关闭、只有显式 `true` 才授予(`'yes'` / `1` / `null` 都不行)、推荐配置不替你打开、导出不带授权、版本号只增不减、以及旧配置读成 0。
|
|
255
255
|
- **`check:rev`** —— 面板的版本号链:写入必须带 `expectedRev`、成功后必须记下宿主的回答、`setRev` 改写活对象、导入不得把版本号清零且要在清空之前读,推荐配置必须走一次 `adoptRecommended` 而不是自己 `resetStore` 再写,且配置写入必须串成一条链、图片字节要等配置落盘之后再删(导入主题也一样)、AI 加的图片用时钟派生的槽位名、两条路径不能同时采用推荐配置。少了任何一环,下一次保存就会判自己陈旧,改动在画面上自己撤销("点一次 + 卡片闪一下后消失")。
|
|
256
|
+
- **`check:meta`** —— 插件在插件管理器和设置页里如何描述**它自己**:`locale/<语言>.json` 每种语言各带标题与描述、两份文件都在 `exports` 里(读取方走 Node 的 ESM 解析器,磁盘上有但 `exports` 没写等于解析不到,而且会被**静默当成不存在**)、都在 `files` 里(否则发布的包里根本没有,症状和上一句一模一样),以及一个相对路径、留在包内、SVG/PNG/JPEG/WebP、256 KiB 以内、带 36×36 viewBox 且不引用外部资源的图标。dsh 就装在旁边时,最后会直接问 `readPluginMeta` 本人——因为它给出的兜底答案正是包名,而那恰是卡片上原来显示的东西。
|
|
256
257
|
- **`check:node`** —— 把构建好的 node 半边通过真实的 RPC 处理器跑一遍(`DSH_HOME` 指向临时目录、`fetch` 换成桩):节日配置块、节日画按内容哈希的缓存与清理、三个边缘的回落、逐图颜色与逐图效果的抬升、全局切换效果、配置的原子写与备份/恢复、图片存储的用量报告与清理,以及推荐配置的七张图(含旧清单方法的消失、槽位白名单、超时与重试预算)。
|
|
257
258
|
|
|
258
259
|
## 常见问题
|
|
@@ -309,34 +310,13 @@ pnpm test # 构建 lib/、类型检查、跑十三道检查
|
|
|
309
310
|
|
|
310
311
|
> 这里只列最近两个版本;更早的版本见 [CHANGELOG.zh.md](./CHANGELOG.zh.md)。
|
|
311
312
|
|
|
312
|
-
### v0.12.
|
|
313
|
-
|
|
314
|
-
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
-
|
|
319
|
-
- **面板 3 秒核对一次版本号**,AI 改完不用刷新;授权关闭时是空操作。
|
|
320
|
-
- **`SCHEMA_VERSION` 升到 11**,新增 `check:agent`,`check:node` 补上陈旧写入与授权往返。
|
|
321
|
-
|
|
322
|
-
### v0.11.0
|
|
323
|
-
|
|
324
|
-
- **下载源换成 B 站图床** —— 推荐配置的七张壁纸与中秋、国庆两张节日画,全部改从 `i0/i1/i2.hdslb.com` 取,三个边缘互为回落;README 里那三张截图仍留在原处,它们不参与运行时。
|
|
325
|
-
- **推荐配置的规则改成随插件内置** —— 七条模型规则与那套界面数值编译进包里,按钮只下载七张图。于是它不再需要 GitHub 能通,也不再有「远端配置比插件新」这道闸和 `preset.json` 清单 —— 能被安装的规则永远就是这份构建自己写的那些。
|
|
326
|
-
- **请求清单变成一张常量表** —— 槽位 → BFS 路径编译期定死,而 BFS 路径是上传内容的哈希,所以壁纸地址天然不可变,不像 git tag 那样能被重新指向别的字节。
|
|
327
|
-
- **地址带 `@3840w.webp`** —— 上传的原图是 2.4–12 MB 的 PNG(九张合计 76 MB),加上这个后缀才是 250–365 KB 的 4K WebP,与现有数据目录里那几份字节的 sha1 完全一致。
|
|
328
|
-
- **节日画的缓存目录按内容哈希分代** —— 从 `holiday-cache/<tag>/` 改成 `holiday-cache/<哈希前八位>/`。换图就换地址、换目录、必然重下,那个「记得顺手把版本号也改了」的坑从此不存在;旧的 tag 目录会在新图落盘后由同一次清扫带走。
|
|
329
|
-
- **`SCHEMA_VERSION` 仍是 10** —— 这次没有字段进出配置形状:变的是这些数值从哪来,不是它们长什么样。
|
|
330
|
-
- **门禁** —— `check:preset` 改钉内置配置本身(规则顺序、槽位 ↔ 地址表、地址里的 webp 变换与内容哈希、缓存分代),`check:node` 重写节日与推荐配置两节(三个边缘的回落与重试预算、旧 `fetchPresetConfig` 方法已不存在、槽位白名单、tag 目录被清扫),`check:scheme` 第 3 节不再联网。
|
|
331
|
-
|
|
332
|
-
### v0.10.0
|
|
333
|
-
|
|
334
|
-
- **配置改成原子写,并留一份 `.bak`** —— 保存先写临时文件再改名覆盖,覆盖前把当前能解析的那份留成备份;主文件坏了就从备份恢复,而不是退回出厂默认、再被你下一次拖动覆盖掉。
|
|
335
|
-
- **透明度、亮度与模糊改成逐图保存** —— 与布局模式、取景、主题色同一层;schema-9 的规则级三个值读取时抬到每张图上,升级不改屏幕。
|
|
336
|
-
- **`SCHEMA_VERSION` 升到 10** —— 字段搬了位置,旧宿主会静默丢掉它们,所以必须让浏览器半边知道。
|
|
337
|
-
- **模糊的壁纸不再在视口四周画一圈黑边** —— 图层盒子向屏幕外各扩 2σ 再裁掉,取景位置补回同样的距离,模糊因此取样到屏幕之外,边缘不再透出背后页面的颜色。
|
|
338
|
-
- **透明度、亮度或模糊不同的两张图之间切换现在有动画了** —— 每个图层记住自己那张图的滤镜,壁纸透明度也跟着过渡走,不再直接切。
|
|
339
|
-
- **拖动这三个滑块不再每帧整块重绘** —— 拖动只写那个字段自己的属性,松手才走一次完整重绘。
|
|
313
|
+
### v0.12.2
|
|
314
|
+
|
|
315
|
+
- **插件管理器和设置页里能正确描述这个插件了** —— `locale/en.json` 与 `locale/zh.json` 分语言给出标题与描述,`icon.svg`(36×36,和内置图标同一个 viewBox)顶掉那个通用方块。两样都写进了 `exports` 和 `files`:读取方走 Node 的 ESM 解析器,磁盘上有但 `exports` 没声明的 locale 文件解析不到,没写进 `files` 的文件发布的包里根本没有——这两种情况在界面上都长得像"根本没有 locale",且不报任何错。`check:meta` 把这些全钉住,最后直接问 `readPluginMeta` 卡片上会显示什么。发布闸门也改成支持 `files` 里的通配符了,`locale/*.json` 不会再被当成一个不存在的字面文件名。
|
|
316
|
+
|
|
317
|
+
### v0.12.1
|
|
318
|
+
|
|
319
|
+
- **修掉"AI 加的图片没有主题色"** —— 自动取色原来只挂在面板自己的上传路径上,而 AI 的 `add_image` 一条都不走:node 半边下载并写配置,浏览器半边只能接盘一个新版本号。现在两处接盘都会给"接盘前不存在的槽位"取色,AI 加的图和手动加的一样有主题色,工具描述里那句话才算数。
|
|
340
320
|
|
|
341
321
|
## Star History
|
|
342
322
|
|
package/icon.svg
ADDED
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 36 36" fill="none">
|
|
2
|
+
<defs>
|
|
3
|
+
<linearGradient id="j1" x1="8" y1="12" x2="28.5" y2="32" gradientUnits="userSpaceOnUse">
|
|
4
|
+
<stop stop-color="#69B9FF"/><stop offset="1" stop-color="#324DE2"/>
|
|
5
|
+
</linearGradient>
|
|
6
|
+
<clipPath id="jclip"><rect x="8.5" y="12" width="20" height="20" rx="5"/></clipPath>
|
|
7
|
+
</defs>
|
|
8
|
+
<rect x="11" y="4.5" width="19" height="19" rx="4.5" transform="rotate(9 20.5 14)" fill="#4561EE" opacity=".3"/>
|
|
9
|
+
<rect x="6" y="9" width="19" height="19" rx="4.5" transform="rotate(-6 15.5 18.5)" fill="#4561EE" opacity=".55"/>
|
|
10
|
+
<rect x="8.5" y="12" width="20" height="20" rx="5" fill="url(#j1)"/>
|
|
11
|
+
<g clip-path="url(#jclip)">
|
|
12
|
+
<circle cx="15.4" cy="17.8" r="2.1" fill="#fff" opacity=".95"/>
|
|
13
|
+
<path d="M11.6 27.6l4.7-4.7 3.1 3.3 2.1-1.9 4.3 4.2" stroke="#fff" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round" opacity=".92"/>
|
|
14
|
+
</g>
|
|
15
|
+
</svg>
|
package/lib/client.js
CHANGED
|
@@ -9024,9 +9024,11 @@ window.__ModuleLoader__.load({
|
|
|
9024
9024
|
if (rev === null || rev === cfg.rev) return;
|
|
9025
9025
|
const persisted = await loadPersisted();
|
|
9026
9026
|
if (persisted === null) return;
|
|
9027
|
+
const before = new Set(cfg.rules.flatMap(ruleSlots));
|
|
9027
9028
|
adoptConfig(persisted.config);
|
|
9028
9029
|
for (const slot of cfg.rules.flatMap(ruleSlots)) if (displayImageOf(slot) === null) await loadSlot(slot);
|
|
9029
9030
|
applyActive();
|
|
9031
|
+
themeArrivedPictures(before);
|
|
9030
9032
|
})();
|
|
9031
9033
|
}
|
|
9032
9034
|
});
|
|
@@ -9042,10 +9044,12 @@ window.__ModuleLoader__.load({
|
|
|
9042
9044
|
applyActive();
|
|
9043
9045
|
})();
|
|
9044
9046
|
setConflictHandler((config) => {
|
|
9047
|
+
const before = new Set(cfg.rules.flatMap(ruleSlots));
|
|
9045
9048
|
adoptConfig(config);
|
|
9046
9049
|
(async () => {
|
|
9047
9050
|
for (const slot of cfg.rules.flatMap(ruleSlots)) if (displayImageOf(slot) === null) await loadSlot(slot);
|
|
9048
9051
|
applyActive();
|
|
9052
|
+
themeArrivedPictures(before);
|
|
9049
9053
|
})();
|
|
9050
9054
|
});
|
|
9051
9055
|
ctx.effect(() => () => {
|
|
@@ -9106,6 +9110,32 @@ window.__ModuleLoader__.load({
|
|
|
9106
9110
|
});
|
|
9107
9111
|
const maybeAutoExtract = (id, slot) => extract.one(id, slot);
|
|
9108
9112
|
const maybeAutoExtractEach = (id, slots) => extract.each(id, slots);
|
|
9113
|
+
/**
|
|
9114
|
+
* Theme the pictures an EXTERNAL writer added.
|
|
9115
|
+
*
|
|
9116
|
+
* The panel's own uploads call `maybeAutoExtract` themselves, because they know
|
|
9117
|
+
* which slots they just appended. The agent's `add_image` does not come through
|
|
9118
|
+
* any of them: it downloads inside the node half, writes the config, and this
|
|
9119
|
+
* half learns about the picture only by adopting a newer revision — the poll
|
|
9120
|
+
* above, or the stale-write handler below. Nothing on that road asked for a
|
|
9121
|
+
* colour, which is why a tool-added picture stayed on the system theme while the
|
|
9122
|
+
* same picture added by hand was themed.
|
|
9123
|
+
*
|
|
9124
|
+
* `before` is the slot set this half held BEFORE adopting, so "new" means a slot
|
|
9125
|
+
* that was not there a moment ago. That comparison is the whole point:
|
|
9126
|
+
* `color === null` cannot be the test, because null is ALSO what the clear
|
|
9127
|
+
* button stores, and re-theming a picture whose colour the user deliberately
|
|
9128
|
+
* removed would be this feature fighting that choice.
|
|
9129
|
+
*
|
|
9130
|
+
* Holiday art is excluded by construction — this walks `rules`, and a festival
|
|
9131
|
+
* slot is read-only.
|
|
9132
|
+
*/
|
|
9133
|
+
const themeArrivedPictures = (before) => {
|
|
9134
|
+
for (const rule of cfg.rules) {
|
|
9135
|
+
const fresh = rule.images.filter((i) => !before.has(i.slot)).map((i) => i.slot);
|
|
9136
|
+
if (fresh.length > 0) maybeAutoExtractEach(rule.id, fresh);
|
|
9137
|
+
}
|
|
9138
|
+
};
|
|
9109
9139
|
const activeLang = () => {
|
|
9110
9140
|
try {
|
|
9111
9141
|
const snapshot = ctx.locale.getSnapshot();
|
package/locale/en.json
ADDED
package/locale/zh.json
ADDED
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "dsh-background-by-model",
|
|
3
|
-
"version": "0.12.
|
|
3
|
+
"version": "0.12.2",
|
|
4
4
|
"description": "Appearance plugin for DeepSeek Harness: an ordered list of model rules, each carrying its own wallpapers — every image with its own framing and theme color — plus layout mode, opacity, brightness and blur; the background follows the model you switch to, a rule can rotate through several images on its own rhythm, and an off-by-default switch lets the agent change any of it through two tools.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"deepseek-harness",
|
|
@@ -21,6 +21,7 @@
|
|
|
21
21
|
},
|
|
22
22
|
"license": "MIT",
|
|
23
23
|
"author": "Tkingxiao",
|
|
24
|
+
"icon": "./icon.svg",
|
|
24
25
|
"type": "module",
|
|
25
26
|
"engines": {
|
|
26
27
|
"dsh": ">=0.2.1-alpha.2"
|
|
@@ -35,13 +36,16 @@
|
|
|
35
36
|
"./client": {
|
|
36
37
|
"default": "./lib/client.js"
|
|
37
38
|
},
|
|
38
|
-
"./package.json": "./package.json"
|
|
39
|
+
"./package.json": "./package.json",
|
|
40
|
+
"./locale/*.json": "./locale/*.json"
|
|
39
41
|
},
|
|
40
42
|
"main": "lib/index.js",
|
|
41
43
|
"directories": {
|
|
42
44
|
"lib": "lib"
|
|
43
45
|
},
|
|
44
46
|
"files": [
|
|
47
|
+
"icon.svg",
|
|
48
|
+
"locale/*.json",
|
|
45
49
|
"lib/index.js",
|
|
46
50
|
"lib/invariant.js",
|
|
47
51
|
"lib/client.js",
|
|
@@ -67,8 +71,9 @@
|
|
|
67
71
|
"check:scheme": "node scripts/scheme-check.ts",
|
|
68
72
|
"check:store": "node scripts/store-check.ts",
|
|
69
73
|
"check:node": "node scripts/node-half-check.mjs",
|
|
70
|
-
"test": "tsdown && tsc -p tsconfig.json && node scripts/holiday-check.ts && node scripts/rotation-check.ts && node scripts/transition-check.ts && node scripts/repaint-check.ts && node scripts/code-plate-check.ts && node scripts/image-mode-check.ts && node scripts/rules-view-check.ts && node scripts/preset-check.ts && node scripts/ui-strings-check.ts && node scripts/watchdogs-check.ts && node scripts/scheme-check.ts && node scripts/store-check.ts && node scripts/agent-access-check.ts && node scripts/rev-check.ts && node scripts/node-half-check.mjs",
|
|
74
|
+
"test": "tsdown && tsc -p tsconfig.json && node scripts/holiday-check.ts && node scripts/rotation-check.ts && node scripts/transition-check.ts && node scripts/repaint-check.ts && node scripts/code-plate-check.ts && node scripts/image-mode-check.ts && node scripts/rules-view-check.ts && node scripts/preset-check.ts && node scripts/ui-strings-check.ts && node scripts/watchdogs-check.ts && node scripts/scheme-check.ts && node scripts/store-check.ts && node scripts/agent-access-check.ts && node scripts/rev-check.ts && node scripts/plugin-meta-check.ts && node scripts/node-half-check.mjs",
|
|
71
75
|
"check:agent": "node scripts/agent-access-check.ts",
|
|
76
|
+
"check:meta": "node scripts/plugin-meta-check.ts",
|
|
72
77
|
"check:rev": "node scripts/rev-check.ts"
|
|
73
78
|
},
|
|
74
79
|
"devDependencies": {
|