🎁 福利专区全网大模型免费应用 + 新用户福利 + 注册活动入口,低成本玩转 AI

壁纸背景 gnk478/dsh-client-ui-wallpaper

DeepSeek Harnessv1.1.8
gnk47828 天前有提交已提供中文文档扫描:含敏感能力

把本地图片 / 视频用作 DSH 桌面客户端的背景,例如 Dynamic Wallpaper.app…

30.7/100
综合分
1
GitHub 星标
556
npm 周下载
—/5
用户评分

数据截至 2026/10/7 · 周下载取自 npm 全网(含 CI / 镜像),非本站安装数;综合分由星标、活跃度与兼容性检查合成。

安装命令 · 需先装 dsh CLI 引擎
dsh plugin --profile web add dsh-client-ui-wallpaper
npm 源 · dsh-client-ui-wallpaper 的发布者账号已校验与本仓库一致

状态速览

判定依据:实装验证 · 静态安装检查 · 自动扫描 · 仓库维护状态
信任档位:需留意
是什么
dsh 原生插件 · vision
装得上吗
实装验证未通过(runtime_smoke_failed),装前请到仓库确认最近更新与 issue
L4 · 真实安装等级说明 →
安全吗
本站尚未对该插件做风险分级
暂未覆盖,不等同于无风险
还在维护吗
活跃:最近一次提交在 28 天前
档位由哪些信号合成

本站实装验证(真实安装 L4 覆盖全站;L5 为运行时冒烟或实机截图,覆盖范围小于 L4) · 验证所用 dsh 版本 · 静态安装检查 · 风险分级 · 仓库维护状态。 下方各区块是它的证据明细。

验证判据与等级说明 →
⚠︎ 实装验证未通过(runtime_smoke_failed · 2026/10/31) ——可能是验证环境差异,装前建议到 GitHub 仓库确认最近更新与 issue。
社区实装还没有人打卡 · 装过的第一个就是你
安装兼容性检查✓ 自动检查通过
展开查看检查明细 ↓

以下结论由程序自动检查 npm 包、engines 声明与入口文件得出,未做人工实机验证——能装不等于用着没问题。

✓npm 包dsh-client-ui-wallpaper @ 1.1.8
✓Node 引擎要求 >=20 · 基线 Node 22.19 满足
✓dsh CLI 依赖未声明 dsh 版本约束
✓入口文件main/exports/bin 已声明

验证方式:npm registry 存在性 + package.json 静态校验 · 最后检查 2026/10/14 04:18:25

安全扫描自动 · 静态分析源码
v2.7.0
🔵 扫描:含敏感能力尚无人工评估
展开查看扫描说明与证据 ↓

静态扫描发现插件具备触达本地系统的能力:执行外部命令、读写/删除本地文件、读取剪贴板或密钥类环境变量(至少其一)。这是能力清单,不是危险判定——具体能力项与证据见下方,安装前请自行判断是否需要。

可执行外部命令读写/删除本地文件发起外部网络请求
查看扫描证据(共 42 处,展示前 24 条)
  • 读取本地文件
    lib/index.js:80
    const parsed = JSON.parse(await readFile(STATE_FILE, 'utf8'));
  • 写入本地文件
    lib/index.js:90
    await mkdir(dirname(STATE_FILE), { recursive: true });
  • 写入本地文件
    lib/index.js:92
    await writeFile(temp, JSON.stringify(next, null, 2) + '\n', { mode: 0o600 });
  • 写入本地文件
    lib/index.js:93
    await rename(temp, STATE_FILE);
  • 读取本地文件
    lib/index.js:116
    entries = await readdir(dir, { withFileTypes: true });
  • 写入本地文件
    lib/index.js:147
    await mkdir(THUMB_DIR, { recursive: true });
  • 写入本地文件
    lib/index.js:149
    await mkdir(scratch, { recursive: true });
  • 执行外部命令来自配置/变量
    lib/index.js:152
    execFile(THUMB_TOOL, ['-t', '-s', '480', '-o', scratch, source], { timeout: 30000 }, (error) => (error ? fail(error) : settle()));
  • 读取本地文件
    lib/index.js:154
    const produced = (await readdir(scratch)).find((entry) => entry.toLowerCase().endsWith('.png'));
  • 写入本地文件
    lib/index.js:156
    await rename(join(scratch, produced), target);
  • 删除本地文件递归
    lib/index.js:158
    await rm(scratch, { recursive: true, force: true }).catch(() => {});
  • 读取本地文件
    lib/index.js:162
    const info = await stat(target);
  • 读取本地文件
    lib/index.js:200
    createReadStream(target, { start, end }).pipe(res);
  • 读取本地文件
    lib/index.js:214
    const taken = await stat(candidate).then(() => true).catch(() => false);
  • 删除本地文件
    lib/index.js:224
    await rm(target, { force: true });
  • 删除本地文件递归
    lib/index.js:276
    try { await rm(full, { recursive: true, force: true }); removed += 1; } catch {}
  • 删除本地文件
    lib/index.js:280
    try { await rm(full, { force: true }); removed += 1; } catch {}
  • 删除本地文件
    lib/index.js:692
    if (kind === 'video') await rm(join(THUMB_DIR, name + '.png'), { force: true }).catch(() => {});
  • 发起网络请求
    lib/client.js:778
    fetch(ROUTE + "/_client", { method: "POST", headers: { "content-type": "application/json" }, body: JSON.stringify(payload) }).catch(function () {});
  • 发起网络请求
    lib/client.js:901
    fetch(ROUTE + "/state", {
  • 发起网络请求
    lib/client.js:1042
    fetch(ROUTE + '/state', { cache: 'no-store' })
  • 发起网络请求
    lib/client.js:1054
    fetch(ROUTE + "/state", { cache: "no-store" })
  • 发起网络请求
    lib/client.js:1115
    fetch(ROUTE + "/list.json", { cache: "no-store" })
  • 发起网络请求
    lib/client.js:1119
    fetch(ROUTE + "/state", { cache: "no-store" })
扫描于 2026/11/2(1 天前) · 范围 入口闭包 + 全包扫描 · 来源 npm 发布包

静态扫描只反映源码中出现的调用,不构成安全背书;人工评估与自动扫描相互独立、互不覆盖。

给这个插件打分还没有人投票↓
用户评分
还没有人投票,来当第一个

功能亮点

  • 本地图片设为壁纸
  • 本地视频设为壁纸

把本地图片、视频(Dynamic Wallpaper.app 素材)用作 DSH 桌面客户端壁纸的客户端插件 · 为 DeepSeek Harness 桌面客户端提供壁纸、图片背景的插件

v1.1.82026-10-06
· 1.1.8 — 清单与安装体验(无代码改动) · 进社区市场:向 awesome-dsh-plugin 提交条目 PR #6667(category: theme),收录后可在 dsh-market 的 Themes 页一键安装 / 升级 · 清单补齐:dsh.client.immediately: true(客户端插件随宿主启动即挂载,壁纸层与设置面板不再等懒加载);engines.dsh: ">=0.2.0-rc.2"(dshmarket 的 manifestFacts() 读 engines.dsh) · README 安装段改为生态标准路径:桌面端用 App 内插件市场(dsh plugin --profile desktop 会被 Electron 独占管理拒绝);其他 profile 一行 dsh plugin --profile web add dsh-client-ui-wallpaper;升级要写版本号(pnpm 11 minimumReleaseAge=24h 冷却);scripts/install.mjs 降级为 fallback · screenshots.json:市场按自己仓库里的这份清单取图,以后换图不用再提 PR 无代码改动:lib/client.js 与 lib/index.js 与 1.1.7 逐字节一致(sha256 3f609150… / 7d7567b9…)——已经在跑插件的用户不需要重新安装。 · 安装 / 升级 · 桌面 App:设置 → 插件市场(收录后) · 其他 profile(web / 自建): dsh plugin --profile web add dsh-client-ui-wallpaper@1.1.8 · 手动 fallback: npm i dsh-client-ui-wallpaper@1.1.8 node node_modules/dsh-client-ui-wallpaper/scripts/install.mjs --profile desktop
v1.1.72026-10-06
· 1.1.7 — 面板手选失效修复 + 点击留痕 · 修复 · 点缩略图完全没反应(1.1.6 回归):modeAfterPick() 被定义在 apply() 内部,而面板 wallpaperSettingsElement() 属于工厂作用域,onClick 闭包取不到它 —— 每次点击同步抛 Uncaught ReferenceError: modeAfterPick is not defined,save() 从未执行。现在函数提升回工厂作用域,轮换开着时手选仍然只改「当前这一张」。 · 手选优先显示:三处手选都带 pick: "image" | "video"(宿主校验/持久化,非法值 400),rotate 分支优先定位手选的那一类 —— 修掉「轮换开着时手选静态图被上次手选的视频盖住」;只影响首帧,之后照常轮换。 · 新增 · 点击留痕 panelPick:三处面板 onClick 在 save() 前调用 notePick(),/_probe 与 /_client 都能读到 { image, video, at, last }。「点了没反应」时可直接区分「点击没进来」还是「状态没生效」。 · 测试 · node --test 共 54 例(test/rotate.test.mjs +2:pick 压过遗留 video、pick 的素材不在库里也先画它) · node scripts/check.mjs 第 14 节 +2 项(三个入口的 notePick、panelPick 上报),并断言 modeAfterPick 必须留在工厂作用域(2 tabs) · 安装 npm i dsh-client-ui-wallpaper@1.1.7 node node_modules/dsh-client-ui-wallpaper/scripts/install.mjs --profile desktop
v1.1.62026-10-06
· 1.1.6 — 手选壁纸不再关闭自动轮换 · 修复 · 面板里点静态图缩略图 / 动态壁纸缩略图 / 「▶ 动态」按钮 曾经硬编码 mode: "image" / mode: "video",等于顺手把自动轮换关掉(1.1.1–1.1.5 一直如此)。 · 现在统一走 modeAfterPick(cfg.mode, fallback):轮换开着时手选只改「当前这一张」,mode 保持 rotate。 · 选中的素材即使不在轮换列表里也先显示它:rotate 分支改用 locateIndex() 定位起始项(显式选的动态版优先于静态图),未命中时 index 保持 -1、先画这一张,下一拍回到列表开头。 · 客户端 load() 改用库内全量 library 校验 config.image(不再限制在轮换池内),宿主 lib/index.js 同样改为 current.images.includes(wanted)。 · 测试 · node --test 52 例(+6:test/rotate.test.mjs 池外静态图 / 池外动态 / 动态优先,test/client.test.mjs modeAfterPick 3 例)。 · 红绿验证:把测试指向 1.1.5 的源码时 4 例失败(缺 modeAfterPick + 3 个池外用例实际值被换成轮换池首项),指向修复后源码 52/52 通过。 · scripts/check.mjs 新增第 14 节(13 项)。 · 安装 / 升级 npm i dsh-client-ui-wallpaper@1.1.6 node node_modules/dsh-client-ui-wallpaper/scripts/install.mjs --profile desktop · 校验 · registry dist.shasum c780d4976d5c25d088ff00383c3ef0e9aa05f38a,tarball 内 package/lib/client.js sha256 4220e444…4228c(与仓库一致) · 可信发布(OIDC):provenance transparency log index 3092177718,2 条 attestations(npm publish v0.1 + SLSA provenance v1,builder github-hosted)
数据来自仓库的 GitHub Release,可能与插件实际版本不一致。

README

由 DeepSeek 最新模型翻译生成
dsh-client-ui-wallpaper 把本地图片 / 视频用作 DSH 桌面客户端的背景,例如 Dynamic Wallpaper.app 播放列表里的素材:整窗铺满、背景模糊、面板与左右侧栏透明度分别可控,字色跟着壁纸明暗自动切换。 这是 ~/.dsh/profiles/desktop/plugins/dsh-client-ui-wallpaper 的完整项目版:含挂载声明、安装脚本、自检脚本与文档;已发布到 npm(dsh-client-ui-wallpaper)。 设置 · 壁纸 上图为真实运行截图(macOS 客户端,设置 → 壁纸):轮换选择与「23 项参与轮换」、自动轮换间隔 60 分钟、只轮换深色 5 项 / 浅色 17 项、浅色壁纸用深色字、自动加入新壁纸、毛玻璃 9px、右侧栏透明度 70%,下方是动态壁纸缩略图网格(每格右上角标注该壁纸的明暗判定)。截图为整幅实拍原图(未裁切、未遮挡、未修饰),仅等比缩放到 1800px 宽。
展开完整文档(README 剩余 1 节)
dsh-client-ui-wallpaper

把本地图片 / 视频用作 DSH 桌面客户端的背景,例如 Dynamic Wallpaper.app 播放列表里的素材:整窗铺满、背景模糊、面板与左右侧栏透明度分别可控,字色跟着壁纸明暗自动切换。

这是 ~/.dsh/profiles/desktop/plugins/dsh-client-ui-wallpaper 的完整项目版:含挂载声明、安装脚本、自检脚本与文档;已发布到 npm(dsh-client-ui-wallpaper)。

设置 · 壁纸

上图为真实运行截图(macOS 客户端,设置 → 壁纸):轮换选择与「23 项参与轮换」、自动轮换间隔 60 分钟、只轮换深色 5 项 / 浅色 17 项、浅色壁纸用深色字、自动加入新壁纸、毛玻璃 9px、右侧栏透明度 70%,下方是动态壁纸缩略图网格(每格右上角标注该壁纸的明暗判定)。截图为整幅实拍原图(未裁切、未遮挡、未修饰),仅等比缩放到 1800px 宽。

功能

背景

- 图片或视频铺满整窗(object-fit: cover),面板半透明让壁纸透出来;弹窗保持不透明
- 背景模糊可调(0–60px);可选纱层(浅色外观白纱 / 深色外观黑纱)
- 静态与动态分开:图片可配「同名视频」,网格里用 ▶ 动态 一键切换
- 轮换:间隔 15 秒–24 小时可调;支持「全选 / 仅深色动态 / 清空 / 默认」

可读性(墨水)

- 按壁纸亮度自动切深/浅字(含代码块、行内 code、气泡、工具栏、输入框与 caret)
- 代码块只跟外观走:浅色外观浅底深字、深色外观深底浅字(绕开 pre.shiki 透明背景导致的误判)
- 设置弹窗内的字色复位为「该外观本来的值」,不被壁纸影响

面板与控件(设置 → 壁纸)

| 控件 | 说明 |
| 壁纸网格 | 静态/动态分组,缩略图 + 深/浅角标 + ✓/+ 轮换勾选 + 当前/播放中标记 |
| 背景模糊 | 滑块 + − [数字框] + 精确步进(0–60,居中、无原生箭头) |
| 右侧栏透明度 | 0–100% 线性,独立于面板;左栏保持原透明观感 |
| 只轮换深色 / 只轮换浅色 | 优先用缩略图实测亮度判定,未采样时按配置名单取反 |
| 自动加入新壁纸 | 新丢进目录的素材自动入库并追加进轮换 |
| 自动轮换 / 间隔 | 秒数可调;可勾「随机轮换」(不会连续两次同一张) |
| 手动选择不打断轮换 | 点缩略图(静态或动态)只换「当前这一张」,轮换照旧(1.1.6 起);选中的素材即使不在轮换列表里也先显示它,下一拍回到列表继续 |
| 视频省电暂停 | 窗口不可见时暂停播放,回到前台自动续播(隐藏期间不切新壁纸) |
| 轮换过渡 | 交叉淡入淡出 0.7s;系统开启「减少动态效果」或窗口隐藏时直接切换 |
| 首帧就绪再淡入 | 新壁纸等首帧解码完成(视频 loadeddata、图片 load/decode,最多等 600ms)才开始淡入,避免大视频「先透明后硬切」 |
| 图层自愈 | 每 10 秒审计一次壁纸层:除面纱与当前节点外,活过过渡宽限(700ms + 250ms)的节点一律判定为残留并回收;层内每个节点的 tag/来源/暂停/透明度/存活时长都上报到 /_probe 的 layerDetail |
| 探针实时化 | 每次切换壁纸后 0.6 秒、以及每 60 秒再发一次 /_probe,switches / layerDetail / audit / prewarm 都是最新值(1.1.1 之前只在启动后 1.5 秒上报一次) |
| 大文件不预热 | 预热前先取素材大小(1.1.4 起宿主在 list.json 里直接给 sizes,取不到才回退 HEAD),超过 50MB 的素材不提前建节点(库里最大的视频 196MB),/_probe 的 prewarm 记录 warmed / skipped / dropped 与最近一次的字节数 |
| 加载失败不静默 | list.json 加载链一旦抛错,错误名与 message 会记进 loadFailure(/wallpaper/_probe 与 /wallpaper/_client 都带),并在下一次成功加载后清空——不再出现「面板正常但壁纸整块空白、没有任何线索」 |
| 选择器失效不静默 | 客户端每 60 秒体检 8 组界面挂钩(输入框/侧栏/右栏/弹窗/气泡/工具栏/头像/代码块):带锚点(textarea、[class="sidebar"]、[aria-modal="true"] 等)的一组连续两轮都匹配不到才算失效(避开 React 渲染中途的假警报),此时 console.warn 并把 missing / detail 写进 /wallpaper/_probe 的 selectorHealth——DSH 升级后「样式悄悄没生效」有据可查 |
| 浅色壁纸用深色字 | 关掉就固定用浅色字 |
| 同步播放列表 | 一键把 Dynamic Wallpaper.app 播放列表里的素材同步进来 |
| 删除(缩略图悬停) | 移到「废纸篓」(可恢复)+ 删缩略图缓存 + 从轮换移除 + 记入同步跳过名单 |
| 侧栏小圆钉 | 与头像中心对齐的收起按钮,点空白处自动收回 |

安装

要求宿主 DSH ≥ 0.2.0-rc.2(本插件实际测试的版本)。装完刷新页面(或重启 DSH),打开 设置 → 壁纸。

A. 桌面 App:App 内插件市场(推荐) DSH Desktop 的 desktop profile 由 Electron 应用独占管理,命令行会直接拒绝(profile "desktop" is managed exclusively by the Electron application),所以桌面端请在 设置 → 插件市场 里搜索安装。本插件已提交社区注册表 awesome-dsh-plugin(条目文件),收录后即可在市场一键安装与升级。

B. 其他 profile(web / 自建 profile):一行命令

dsh plugin --profile web add dsh-client-ui-wallpaper

CLI 会把包装进 profile 的 node_modules,并自动把包名追加到 profile 的 dsh.profile.bundles——cordis.patch.yml 不需要手动改。命令行需要 pnpm 在 PATH。

升级要写版本号:pnpm 11 默认 minimumReleaseAge=24h,发布未满 24 小时的版本,dsh plugin add <包名> 与 @latest 都只会装到上一版(并提示 x.y.z is available)。要立刻升级请指定版本:
dsh plugin --profile web add dsh-client-ui-wallpaper@1.1.8

C. 手动安装(fallback)

profile 已经被手动改过、或环境里没有 dsh 命令时用;会直接改 profile 的 cordis.patch.yml(先备份):

npm i dsh-client-ui-wallpaper
node node_modules/dsh-client-ui-wallpaper/scripts/install.mjs --profile desktop

从源码同理:

git clone https://github.com/gnk478/dsh-client-ui-wallpaper.git
cd dsh-client-ui-wallpaper
node scripts/install.mjs --profile desktop

profile 的 package.json / cordis.patch.yml 归插件管理器所有,手写的 insert 行可能在它下次操作时被覆盖——能用市场或 CLI 就不要用它。

快速开始

素材二选一:

- 什么都不用做:默认直接读 Dynamic Wallpaper.app 的素材库
~/Library/Containers/whbalzac.Dongtaizhuomian/Data/Documents/{Wallpaper,Videos}
- 用自己的目录:在 config 里写绝对路径(插件不做 ~ 展开),例如 imageDir: /Users/you/.dsh/wallpapers、videoDir: /Users/you/.dsh/videos

mkdir -p ~/.dsh/wallpapers ~/.dsh/videos
cp ~/Pictures/some.jpg ~/.dsh/wallpapers/ # 静态壁纸
cp ~/Movies/some.mp4 ~/.dsh/videos/ # 动态壁纸

node scripts/check.mjs # 自检

配置

config(cordis.patch.yml 的 ui-wallpaper 行,见 examples/profile-cordis.patch.yml)

| 键 | 默认 | 说明 |
| imageDir / videoDir | Dynamic Wallpaper.app 素材库的 Wallpaper/ 与 Videos/(lib/index.js:37-39) | 素材目录,必须是绝对路径(插件不做 ~ 展开) |
| mode | image | image / video / rotate |
| image / video | '' | 固定的文件名 |
| live | false | 图片有同名视频时用视频做动态壁纸 |
| rotateSeconds | 300 | 轮换间隔(秒) |
| shuffle | false | 随机轮换(不会连续两次同一张) |
| blur | 8 | 背景模糊(px) |
| panelOpacity | 0 | 面板不透明度(0 = 全透) |
| windowOpacity | 0.96 | 弹窗不透明度 |
| dim | 0 | 纱层强度 |
| autoInk | true | 按壁纸亮度自动切字色 |
| autoInclude | true | 新素材自动加入轮换 |
| only / darkVideos | [] | 深色壁纸 / 深色动态白名单 |

state(~/.dsh/wallpaper-state.json,面板里改的都落这里)

mode、image、video、live、rotation、only、videoPool、blur、panelOpacity、sidebarOpacity(null = 跟随面板)、autoInk、autoInclude、knownFiles、lastAdded、rotateSeconds、shuffle

直接读/写状态(调试用)
curl -s http://127.0.0.1:19387/wallpaper/statebash
curl -s -X POST -H 'content-type: application/json' \
-d '{"sidebarOpacity":0.35}' http://127.0.0.1:19387/wallpaper/state

与 Dynamic Wallpaper.app 同步

app 的播放列表在:

~/Library/Containers/whbalzac.Dongtaizhuomian/Data/Documents/
├── Videos/ 播放列表素材 ├── Wallpaper/ 静态壁纸 └── Setting/Preferences.json playlist_array(播放列表)

两种同步方式(都只增不删;读取该目录需要给 DSH「完全磁盘访问权限」): bash

面板:设置 → 壁纸 → 同步播放列表

或命令行

./sync-wallpaper-playlist.sh # 只同步播放列表里的视频 ./sync-wallpaper-playlist.sh --stills # 连静态壁纸目录一起

同步会跳过 ~/.dsh/wallpaper-sync-skip.txt 里列出的文件名(删除过的素材会自动写进去,防止被拉回)。

目录结构

dsh-client-ui-wallpaper/
├── lib/
│ ├── index.js 宿主:路由 / 扫描 / 状态 / 抽帧 / 同步 / 删除 │ └── client.js 客户端:注入样式 / 铺背景 / 面板 UI / 墨水判定 ├── scripts/ │ ├── install.mjs 安装进 profile(备份 + 复制 + 写 insert 行) │ └── check.mjs 静态自检(语法 + 路由 + 样式常量 + 控件) ├── docs/ARCHITECTURE.md 架构、路由表、样式常量、踩坑记录 ├── .github/workflows/ check.yml(自检)+ publish.yml(npm 可信发布) ├── examples/profile-cordis.patch.yml 带完整配置的挂载示例 ├── examples/github-workflow-publish.yml publish.yml 副本(方便复制) ├── cordis.patch.yml 本插件的挂载声明 ├── CHANGELOG.md / PROVENANCE.md / LICENSE └── README.md

开发

- 宿主是普通 cordis 插件,改完由 DSH 的 HMR 重载;客户端 lib/client.js 改动会被热替换(注意:热替换会重置模块级变量,需要跨次保留的数据要放 window / sessionStorage)
- 自检:

bash
node scripts/check.mjs
node --test # 行为测试(宿主:路由 / 回收站 / 缩略图 GC;客户端:轮换加载与预热 / crossfade / 首帧就绪 / 图层审计 / applyVars / autoInk / classifyTile / syncBlur / 选择器体检 / 手选不打断轮换 / 手选点击留痕),1.1.7 起共 54 例
curl -s http://127.0.0.1:19387/wallpaper/_client | python3 -m json.tool | head -40 # 客户端自报状态
curl -s http://127.0.0.1:19387/wallpaper/_hits # 各路由请求计数

发布与打包

npm 发布走可信发布(Trusted Publishing / OIDC),不需要 token:

1. 改 package.json 的 version、更新 CHANGELOG.md
2. 在 npm 包设置里配 Trusted Publisher:GitHub Actions → Organization gnk478、Repository dsh-client-ui-wallpaper、Workflow publish.yml,Allowed actions 勾上 npm publish
3. 推 tag 或手动触发 .github/workflows/publish.yml: bash
git tag v1.1.8 && git push origin v1.1.8 # tag 触发
gh workflow run publish.yml # 或手动触发

工作流里 permissions: id-token: write 是关键(OIDC 身份);npm publish 会自动带 provenance。
本地手工发布仍然可用,但需要一个开了 Bypass 2FA 的 Granular Access Token:npm login && npm publish(prepublishOnly 会先跑 scripts/check.mjs 与 node --test)。

Release 附件: bash
git archive --format=zip -o dsh-client-ui-wallpaper-1.1.8.zip HEAD
gh release create v1.1.8 dsh-client-ui-wallpaper-1.1.8.zip

CI:.github/workflows/check.yml 在 push / PR 时跑 node scripts/check.mjs 与 node --test,也是顶部徽章的来源;两个工作流的副本放在 examples/ 下方便复制。

故障排查

| 症状 | 原因 / 处理 |
| 壁纸没铺满 | 面板里确认已选壁纸;检查 /wallpaper/list.json 是否有素材 |
| 点了壁纸完全没反应(1.1.6) | 面板 onClick 用的 modeAfterPick() 被定义在 apply() 内,闭包取不到 → 每次点击同步抛 ReferenceError,save() 从未执行。1.1.7 已把函数提升到工厂作用域;排查时读 /wallpaper/_probe 的 panelPick(点击计数:数字不涨 = 点击没进来;涨了但画面不变 = 状态没生效)与 /_client 的 lastError |
| 点了壁纸,自动轮换就停了(1.1.5 及更早) | 面板手选曾经硬编码 mode: "image" / mode: "video",等于顺手把轮换关掉;1.1.6 起改走 modeAfterPick()——轮换开着时手选只改当前位置,选中的素材不在轮换列表里也先显示它 |
| 壁纸整块空白(面板一切正常) | 1.1.1 / 1.1.2 的已知缺陷:rotate 分支丢了 var seconds / var index 声明,load() 一进分支就抛 ReferenceError,又被静默的 .catch 吞掉 → 壁纸再也不绘制且毫无提示。升级到 1.1.3;之后若再遇到,读 /wallpaper/_probe 的 loadFailure({ at, name, message }) |
| DSH 升级后样式或自动字色悄悄没生效 | 1.1.5 起客户端每 60 秒体检一次界面挂钩,读 /wallpaper/_probe 的 selectorHealth:missing 列出失效的挂钩(missing: [] 即正常),detail 给出每组的匹配数与命中的那条选择器;带锚点的组连续两轮落空才会告警,所以渲染中途不会误报。告警同时会 console.warn("[dsh-wallpaper] UI 选择器失效:…") |
| 侧栏/右栏透明度拖了没反应 | 常见于「透明化扫描」清掉了底色;本版本已对右栏跳过扫描并直接写 background-color。若自行改过选择器,核对 SIDEBAR_CSS / SIDEBAR_LEFT_CSS |
| 代码块字看不清 | 代码块应「只跟外观走」;检查 CODEFIX_CSS 是否注入 |
| 视频缩略图一直是灰的 | 首次访问 /wallpaper/thumb/<name> 会调 qlmanage 抽帧,稍等再刷新;检查 ~/.dsh/wallpaper-thumbs/ |
| 换壁纸没有淡入效果 | 首次绘制、重绘同一张、窗口隐藏、或系统开了「减少动态效果」(prefers-reduced-motion: reduce)时都是直接切换,不做 0.7s 过渡。1.1.1 起淡入会先等新壁纸首帧就绪(最多 600ms),大视频不会再看成「秒切」;用 /wallpaper/_probe 的 switches(lastReason / waited)可确认最近一次为什么没淡。1.1.2 起这些统计是实时的(切换后 0.6 秒 + 每 60 秒刷新),另外 layerDetail 会逐个列出层里残留的节点、audit.removed 显示自愈回收了几个。loadFailure 为 null 说明加载链没抛错 |
| 新素材不出现 | 刷新面板(宿主目录扫描有 4 秒快照缓存,见 lib/index.js:229);确认扩展名在白名单(图片 jpg/jpeg/png/webp/gif/avif/bmp,视频 mp4/webm/mov/m4v) |
| 改了 profile 文件不生效 | DSH 运行中会用内存配置回写 profile 文件;完全退出后再改,或改用「设置」界面 |
| 面板打不开 / 报错 | 看 /wallpaper/_client 的 lastError,以及宿主日志 |

已知限制

- 与 DSH 的布局类名(_6Qf49G_)和色板 token(--dsw-*)耦合,DSH 升级后可能需要同步调整;1.1.5 起这类失效不再静默——每 60 秒体检一次,selectorHealth.missing 会点名落空的那组(detail 给出匹配数)
- 播放列表同步依赖 macOS 的 TCC 权限(完全磁盘访问)与 qlmanage(缩略图抽帧)
- 删除会移到 ~/.Trash(可恢复);素材与废纸篓不在同一卷时 rename 失败,会回退为真删,面板提示「已永久删除」
- 超过 50MB 的素材不做轮换预热,切换时的首次解码在几十毫秒到几百毫秒之间(首帧就绪上限仍是 600ms)
- 图层自愈是兜底手段:正常情况 audit.removed 恒为 0;若它持续增长,layerDetail 会指出是哪个节点、来自哪个文件
- 轮换分支的初始化(seconds / index / 首帧停在哪一项)现在由 test/rotate.test.mjs 用真实源码 + 替身 fetch 跑通:任何未声明变量或提前抛错都会让测试变红,而不是让壁纸静默空白

License

MIT
预览分享卡片长什么样 ↓gnk478/dsh-client-ui-wallpaper
分享 · DeepSeek Harness Hub
gnk478/dsh-client-ui-wallpaper

把本地图片 / 视频用作 DSH 桌面客户端的背景,例如 Dynamic Wallpaper.app…

这是你的仓库?认领条目

回到顶部