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

壁纸引擎背景 pbadgpmeb22791-sketch/dsh-we-wallpaper

DeepSeek Harness
pbadgpmeb22791-sketch60 天前有提交已提供中文文档扫描:含敏感能力

把 Wallpaper Engine 壁纸设为界面动态背景

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

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

自动兼容检查有告警:未发布到 npm registry,仅可从源码安装。
安装命令 · 需先装 dsh CLI 引擎
dsh plugin --profile web add pbadgpmeb22791-sketch/dsh-we-wallpaper
该包不可直接 npm 安装,改从 GitHub 源安装(明细见下方安装检查)

状态速览

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

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

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

未发布到 npm registry,仅可从源码安装

展开查看检查明细 ↓

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

✗npm 包dsh-we-wallpaper(未发布到 npm,仅可源码安装)
✓Node 引擎未声明 engines.node
✓dsh CLI 依赖未声明 dsh 版本约束
✓入口文件main/exports/bin 已声明

验证方式:npm registry 存在性 + package.json 静态校验 · 最后检查 2026/9/22 00:12:03

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

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

可执行外部命令读写/删除本地文件发起外部网络请求
查看扫描证据(共 156 处,展示前 83 条)
  • 读取本地文件
    lib/index.js:678
    const raw = JSON.parse(readFileSync(cachedMetaPath(workshopId, home), "utf8"));
  • 读取本地文件
    lib/index.js:709
    if (existsSync(candidate)) return candidate;
  • 读取本地文件
    lib/index.js:748
    entries = readdirSync(current, { withFileTypes: true });
  • 读取本地文件
    lib/index.js:772
    return statSync(value, { throwIfNoEntry: false })?.isFile() === true;
  • 写入本地文件
    lib/index.js:794
    mkdirSync(outputDir, { recursive: true });
  • 读取本地文件
    lib/index.js:832
    const stat = statSync(file, { throwIfNoEntry: false });
  • 读取本地文件
    lib/index.js:836
    bytes = readFileSync(file);
  • 删除本地文件
    lib/index.js:966
    rmSync(repkgTmp, {
  • 写入本地文件
    lib/index.js:1005
    mkdirSync(cacheDir(home), { recursive: true });
  • 写入本地文件
    lib/index.js:1007
    writeFileSync(tmp, image.bytes);
  • 写入本地文件
    lib/index.js:1008
    renameSync(tmp, file);
  • 写入本地文件
    lib/index.js:1009
    writeFileSync(cachedMetaPath(workshopId, home), JSON.stringify(nextMeta), "utf8");
  • 执行外部命令来自配置/变量
    lib/index.js:1122
    const out = spawnSync(powershellExecutable(), [
  • 执行外部命令来自配置/变量
    lib/index.js:1194
    const out = spawnSync(powershellExecutable(), args, {
  • 写入本地文件
    lib/index.js:1215
    mkdirSync(runtimeDir, { recursive: true });
  • 执行外部命令来自配置/变量
    lib/index.js:1224
    activeRecorder = spawn(runtimeWcap, [], {
  • 执行外部命令来自配置/变量
    lib/index.js:1232
    const open = spawnSync(executable, [
  • 执行外部命令来自配置/变量
    lib/index.js:1262
    const hotkey = spawnSync(powershellExecutable(), [
  • 删除本地文件
    lib/index.js:1293
    rmSync(finalPath, { force: true });
  • 执行外部命令来自配置/变量
    lib/index.js:1312
    spawnSync(executable, [
  • 删除本地文件
    lib/index.js:1327
    rmSync(jobDir, {
  • 发起网络请求
    lib/client.js:102
    const data = await (await fetch("/api/we-wallpaper/list")).json();
  • 发起网络请求
    lib/client.js:724
    const data = await (await fetch(`${API$1}/list`)).json();
  • 发起网络请求
    lib/client.js:839
    fetch(`${API$1}/scene-video/status/${encodedId}`).then(async (response) => {
  • 发起网络请求
    lib/client.js:860
    fetch(`${API$1}/scene-video/generate/${encodedId}`, {
  • 发起网络请求
    lib/client.js:1072
    const data = await (await fetch(`${API}/state`)).json();
  • 发起网络请求
    lib/client.js:1139
    const data = await (await fetch(`${API}/state`, {
  • 发起网络请求
    src/client/layer.ts:215
    const response = await fetch(`${API}/list`)
  • 发起网络请求
    src/client/layer.ts:346
    void fetch(`${API}/scene-video/status/${encodedId}`).then(async (response) => {
  • 发起网络请求
    src/client/layer.ts:370
    void fetch(`${API}/scene-video/generate/${encodedId}`, {
  • 发起网络请求
    src/client/state.ts:54
    const response = await fetch(`${API}/state`)
  • 发起网络请求
    src/client/state.ts:125
    const response = await fetch(`${API}/state`, {
  • 读取本地文件
    src/pkg-preview.ts:104
    const raw: unknown = JSON.parse(readFileSync(cachedMetaPath(workshopId, home), 'utf8'))
  • 读取本地文件
    src/pkg-preview.ts:140
    if (existsSync(candidate)) return candidate
  • 读取本地文件
    src/pkg-preview.ts:177
    try { entries = readdirSync(current, { withFileTypes: true }) } catch { return }
  • 读取本地文件
    src/pkg-preview.ts:195
    try { return statSync(value, { throwIfNoEntry: false })?.isFile() === true } catch { return false }
  • 写入本地文件
    src/pkg-preview.ts:211
    mkdirSync(outputDir, { recursive: true })
  • 读取本地文件
    src/pkg-preview.ts:232
    const stat = statSync(file, { throwIfNoEntry: false })
  • 读取本地文件
    src/pkg-preview.ts:235
    try { bytes = readFileSync(file) } catch { continue }
  • 删除本地文件递归
    src/pkg-preview.ts:327
    try { rmSync(repkgTmp, { recursive: true, force: true }) } catch { }
  • 写入本地文件
    src/pkg-preview.ts:357
    mkdirSync(dir, { recursive: true })
  • 写入本地文件
    src/pkg-preview.ts:359
    writeFileSync(tmp, image.bytes)
  • 写入本地文件
    src/pkg-preview.ts:360
    renameSync(tmp, file)
  • 写入本地文件
    src/pkg-preview.ts:361
    writeFileSync(cachedMetaPath(workshopId, home), JSON.stringify(nextMeta), 'utf8')
  • 删除本地文件
    src/pkg-preview.ts:386
    try { rmSync(file, { force: true }) } catch { }
  • 读取本地文件
    src/routes.ts:98
    const stat = statSync(dir, { throwIfNoEntry: false })
  • 读取本地文件
    src/routes.ts:220
    const stat = statSync(abs, { throwIfNoEntry: false })
  • 读取本地文件
    src/routes.ts:261
    createReadStream(abs, { start, end }).pipe(res)
  • 读取本地文件
    src/routes.ts:266
    createReadStream(abs).pipe(res)
  • 读取本地文件
    src/routes.ts:305
    if (existsSync(abs)) return abs
  • 读取本地文件
    src/routes.ts:469
    if (!existsSync(abs)) {
  • 读取本地文件
    src/scene-video.ts:89
    return statSync(join(entry.dir, 'project.json'), { throwIfNoEntry: false })?.mtimeMs ?? -1
  • 读取本地文件
    src/scene-video.ts:96
    const stat = statSync(video)
  • 读取本地文件
    src/scene-video.ts:98
    const raw = JSON.parse(readFileSync(metaPath, 'utf8')) as Partial<SceneVideoMeta>
  • 读取本地文件
    src/scene-video.ts:152
    if (existsSync(candidate)) return candidate
  • 读取本地文件
    src/scene-video.ts:164
    return existsSync(absolute) ? absolute : 'powershell.exe'
  • 执行外部命令来自配置/变量
    src/scene-video.ts:170
    const out = spawnSync(powershellExecutable(), [
  • 读取本地文件
    src/scene-video.ts:206
    const files = readdirSync(dir)
  • 执行外部命令来自配置/变量
    src/scene-video.ts:235
    const out = spawnSync(powershellExecutable(), args, {
  • 写入本地文件
    src/scene-video.ts:258
    mkdirSync(runtimeDir, { recursive: true })
  • 写入本地文件
    src/scene-video.ts:259
    mkdirSync(jobDir, { recursive: true })
  • 写入本地文件
    src/scene-video.ts:261
    copyFileSync(bundledWcap, runtimeWcap)
  • 写入本地文件
    src/scene-video.ts:262
    writeFileSync(join(runtimeDir, 'wcap-x64.ini'), wcapIni(jobDir, SCENE_VIDEO_SECONDS, monitor.width, monitor.height), 'utf8')
  • 执行外部命令来自配置/变量
    src/scene-video.ts:268
    activeRecorder = spawn(runtimeWcap, [], {
  • 执行外部命令来自配置/变量
    src/scene-video.ts:277
    const open = spawnSync(executable, [
  • 执行外部命令来自配置/变量
    src/scene-video.ts:297
    const hotkey = spawnSync(powershellExecutable(), [
  • 写入本地文件
    src/scene-video.ts:318
    copyFileSync(recorded, tempPath)
  • 删除本地文件
    src/scene-video.ts:319
    rmSync(finalPath, { force: true })
  • 写入本地文件
    src/scene-video.ts:320
    renameSync(tempPath, finalPath)
  • 执行外部命令来自配置/变量
    src/scene-video.ts:335
    spawnSync(executable, ['-control', 'closeWallpaper', '-location', location], {
  • 删除本地文件递归
    src/scene-video.ts:342
    rmSync(jobDir, { recursive: true, force: true })
  • 读取本地文件
    src/state.ts:98
    if (!existsSync(file)) return { ...DEFAULT_STATE }
  • 读取本地文件
    src/state.ts:100
    return normalizeState(JSON.parse(readFileSync(file, 'utf8').replace(/^ FEFF/, '')))
  • 写入本地文件
    src/state.ts:120
    mkdirSync(dirname(file), { recursive: true })
  • 写入本地文件
    src/state.ts:122
    writeFileSync(tmp, JSON.stringify(next, null, 2), 'utf8')
  • 写入本地文件
    src/state.ts:123
    renameSync(tmp, file)
  • 执行外部命令来自配置/变量
    src/we-scanner.ts:71
    const out = spawnSync(join(windir, 'System32', 'reg.exe'), ['query', key, '/v', name], {
  • 读取本地文件
    src/we-scanner.ts:95
    return existsSync(join(dir, 'wallpaper64.exe'))
  • 读取本地文件
    src/we-scanner.ts:96
    || existsSync(join(dir, 'config.json'))
  • 读取本地文件
    src/we-scanner.ts:97
    || existsSync(join(dir, 'projects'))
  • 读取本地文件
    src/we-scanner.ts:120
    if (!existsSync(vdfPath)) continue
  • 读取本地文件
    src/we-scanner.ts:122
    for (const folder of parseLibraryFolders(readFileSync(vdfPath, 'utf8'))) {
  • 读取本地文件
    src/we-scanner.ts:180
    if (existsSync(ws)) workshops.add(ws)
扫描于 2026/11/4(0 天前) · 范围 入口闭包 + 发布文件清单 · 来源 GitHub 仓库

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

依赖的 DSH / Cordis 模块
@deepseek-ai/cordis@deepseek-ai/dsh-client-locale@deepseek-ai/dsh-client-runtime@deepseek-ai/dsh-client-ui-settings-plugins@deepseek-ai/dsh-client-ui-slots@deepseek-ai/dsh-host-webserver@deepseek-ai/dsh-settings
给这个插件打分还没有人投票↓
用户评分
还没有人投票,来当第一个

功能亮点

  • 接入壁纸库作背景
  • 支持视频网页场景壁纸
  • 场景壁纸全屏高清缓存
展开完整介绍(135 字)↓

把 Wallpaper Engine 壁纸库用作 DeepSeek Harness(DSH)GUI 背景:支持视频、网页和场景壁纸,场景(.pkg)壁纸还带原生全屏高清缓存。DSH 插件:把 Wallpaper Engine 壁纸接入 DeepSeek Harness。

README

由 DeepSeek 最新模型翻译生成
dsh-we-wallpaper 将你的本地 Wallpaper Engine 库用作 DeepSeek Harness Web GUI 的背景——视频壁纸会播放、网页壁纸会渲染,并且场景壁纸会从 Wallpaper Engine 获得一次性高分辨率动态缓存。 支持热插拔、无依赖、无需修改 dsh 源码。 - 语言:简体中文.md) Screenshots / 演示 壁纸库卡片以及一张作为 GUI 背景应用的场景壁纸: 设置卡片与应用到界面背景的场景壁纸: demo-1 demo-2 功能特性 - 将壁纸作为 GUI 背景播放 - video 壁纸会作为循环播放的静音 播放(原生分辨率) - web 壁纸会在沙盒化、可点击穿透的 中渲染 - image 壁纸按原样显示 - 在动态优先模式下,scene 壁纸首先由 Wallpaper Engine 以真正的全屏方式渲染(无边框、置顶、原生显示器分辨率、捕获时隐藏任务栏),并通过 Windows.Graphics.Capture 录制为 12 秒的 H.264 循环视频;后续加载会使用缓存,绝不会放大 160px 的创意工坊预览图 - HD 静态模式和失败回退仍使用无依赖的 .pkg / TEX 解码器来提取精确的 4K–8K 背景纹理
展开完整文档(README 剩余 1 节)
dsh-we-wallpaper

将你的本地 Wallpaper Engine 库用作 DeepSeek Harness Web GUI 的背景——视频壁纸会播放、网页壁纸会渲染,并且场景壁纸会从 Wallpaper Engine 获得一次性高分辨率动态缓存。
支持热插拔、无依赖、无需修改 dsh 源码。

- 语言:简体中文.md)

Screenshots / 演示

壁纸库卡片以及一张作为 GUI 背景应用的场景壁纸:

设置卡片与应用到界面背景的场景壁纸:

demo-1

demo-2

功能特性

- 将壁纸作为 GUI 背景播放
- video 壁纸会作为循环播放的静音 播放(原生分辨率)
- web 壁纸会在沙盒化、可点击穿透的 中渲染
- image 壁纸按原样显示
- 在动态优先模式下,scene 壁纸首先由 Wallpaper Engine 以真正的全屏方式渲染(无边框、置顶、原生显示器分辨率、捕获时隐藏任务栏),并通过 Windows.Graphics.Capture 录制为 12 秒的 H.264 循环视频;后续加载会使用缓存,绝不会放大 160px 的创意工坊预览图
- HD 静态模式和失败回退仍使用无依赖的 .pkg / TEX 解码器来提取精确的 4K–8K 背景纹理
- 官方插件配置区域中的设置卡片(设置 → 插件配置):浏览带实时预览的库、搜索、一键应用,以及标记当前正在你的桌面上运行的壁纸的徽章
- 可读性控制:深色 scrim、面板半透明(官方表面 token 被重新声明为半透明——在浅色和深色主题下均可用)、cover / contain 适配、锐化(用于回退预览源的 SVG 卷积滤镜),以及 动态优先 / HD 静态 场景模式
- 注重资源的播放:壁纸未更改时会复用媒体元素——拖动滑块绝不会重启视频流或产生另一个解码管线(此处修复了一个内存泄漏崩溃问题)
- 持久化选择保存在 ~/.dsh/we-wallpaper.json 中;提取的场景画面缓存于 ~/.dsh/we-wallpaper-cache/

动态缓存

- HD 录制文件位于 ~/.dsh/we-wallpaper-cache/hd-video/ 下,以 Wallpaper Engine 创意工坊 ID 为键,并使用 JSON 元数据进行失效判断。
- 这是一个持久、可重建的缓存,而不是一次性的临时文件。源文件或录制器版本变化会重新生成它;手动删除它是安全的。
- 首次生成会将 Wallpaper Engine 场景窗口置于前台约 15 秒。之后启动 DSH 时会读取缓存的 MP4,不会再次录制。

快速开始

git clone https://github.com/pbadgpmeb22791-sketch/dsh-we-wallpaper.git
dsh plugin --profile desktop add "\new"

使用 dsh-super-injector 时,将插件路径指向 \new 作为好的。仓库根目录保留旧版本以便回滚。

重启(或热重载)dsh 宿主,刷新 GUI 页面,打开设置 → 插件配置 → 动态壁纸,选择一个壁纸,按喜好调整遮罩 / 半透明效果。

所有安装方式(包括手动编辑 cordis.patch.yml 和 dsh-super-injector)请参见 docs/INSTALL.md,所有选项和故障排除指南请参见 docs/USAGE.md。

工作原理

| 部分 | 文件 | 作用 |
| 宿主 | src/we-scanner.ts | 发现 WE 安装位置(环境变量 → Steam 注册表 → libraryfolders.vdf → 默认值)并解析每个 project.json |
| 宿主 | src/pkg-tex.ts | WE 包解码器:目录表、TEXV/TEXB 容器、LZ4、DXT1/3/5、内嵌 PNG/JPEG、PNG 编码 |
| 宿主 | src/pkg-preview.ts | 提取缓存(~/.dsh/we-wallpaper-cache/) |
| 宿主 | src/scene-video.ts | 通过官方 CLI + wcap 构建/缓存高清 H.264 循环视频 |
| 宿主 | src/routes.ts | /api/we-wallpaper/ 路由族 — 同源防护、路径穿越防护 |
| 宿主 | src/state.ts | 选择持久化(~/.dsh/we-wallpaper.json) |
| 浏览器 | src/client/layer.ts | 固定背景层:按类型显示媒体、令牌快照半透明、遮罩、锐化 |
| 浏览器 | src/client/WallpaperCard.tsx | 库卡片(预览、搜索、应用、选项) |

HTTP API

| 路由 | 用途 |
| GET /api/we-wallpaper/list | 壁纸库(id/标题/类型/来源/桌面激活状态) |
| GET/POST /api/we-wallpaper/state | 持久化的选择 + 选项 |
| GET /api/we-wallpaper/preview/ | 本地预览文件(GIF/JPG/PNG) |
| GET /api/we-wallpaper/pkg/ | 提取的场景背景(PNG/JPEG,已缓存) |
| GET /api/we-wallpaper/media/ | 主媒体文件(支持范围请求的视频流) |
| GET /api/we-wallpaper/web// | Web 壁纸的静态文件 |
| POST /api/we-wallpaper/scene-video/generate/ | 生成首个高清动画缓存 |
| GET /api/we-wallpaper/scene-video/status/ | 读取进度 / 失败状态 |
| GET /api/we-wallpaper/scene-video/media/ | 支持范围请求的缓存 H.264 流 |

安全说明

- 每个路由都会拒绝跨站请求(Sec-Fetch-Site / Origin 防护)— 随机网页无法通过 localhost CSRF 读取你的壁纸库
- 壁纸 id 仅针对扫描映射进行解析;Web 文件路径有路径穿越防护
- Web 壁纸在沙盒化、点击穿透的 iframe 中运行 — 它们仍然是你自己的本地文件,请以你在 Wallpaper Engine 中给予工坊内容的同等信任对待它们
- 动态场景仅由本地安装的 Wallpaper Engine 打开。
捆绑的录制器是公有领域的 wcap 二进制文件;其许可证包含在 tools/wcap/LICENSE。

已知限制

- 高清动画缓存需要 Windows 桌面 Harness 以及正在运行的 Wallpaper Engine。首次生成时,场景窗口会进入前台约 15 秒。对于随机/非周期性场景,12 秒循环可能会出现可见接缝。失败时会安全回退到精确的 HD 静态图或本地预览。
- 静态提取首先遵循 scene.json → model → material → TEX 依赖链。仅当场景关系无法识别背景时,才使用尺寸/宽高比启发式方法,因此未知场景仍可能选错纹理。
- 音频已静音(浏览器自动播放策略)
- 半透明重映射覆盖官方 --dsw-alias- 令牌;带有硬编码背景的第三方插件可能仍保持不透明

本次更新修复了什么

旧版可以直接播放视频壁纸,但场景壁纸通常不得不放大一个约 160px 的创意工坊预览图。这保留了动态效果,但看起来明显模糊。v0.3.0 让 Wallpaper Engine 渲染真实场景,然后将最终 HD 输出录制并缓存为 H.264。这样既保留了动画,也保留了清晰度,而无需尝试重新实现完整的 Wallpaper Engine 场景渲染器。

当录制被禁用或失败时,内置静态路径仍可从场景包中解析出真实背景纹理。示例 3409595232 会选择 3840×2160 的 materials/背景.tex,而不是前景角色纹理。未知或受保护的包不会被强制解密;它们会安全失败并返回诊断信息。

路线图

可能的后续工作包括可配置的捕获时长/比特率、缓存空间管理和一键清理、循环接缝改进,以及对更多旧式或特殊 TEX 容器的支持。参见 docs/SUMMARY.md。

开发

npm install
npm run typecheck # tsc over host + client programs
npm test # vitest (pkg decoder, LZ4, DXT, cache, scanner)
npm run build # lib/index.js (host) + lib/client.js (browser bundle)

诊断脚本位于 scripts/(probe-pkg.mjs、probe-previews.mjs、survey-extract.mjs)。完整细节见 docs/DEVELOPMENT.md。

许可证

MIT — DXT 解码包含来自 RePKG 的 LibSquish 衍生 MIT 代码的 TypeScript 移植版(Xalcon @ mmowned.com)。
预览分享卡片长什么样 ↓pbadgpmeb22791-sketch/dsh-we-wallpaper
分享 · DeepSeek Harness Hub
pbadgpmeb22791-sketch/dsh-we-wallpaper

把 Wallpaper Engine 壁纸设为界面动态背景

这是你的仓库?认领条目

回到顶部