dsh-web-ui/packages/skins/skin-center

5.1kStar311Fork51Issue5Watching

dsh 网页端的皮肤中心:内置 15 款皮肤,提供原子切换、试穿、Wallpaper Engine 桥接和首屏防闪屏,是插件市场唯一的皮肤加载器与渲染器。

语言
TypeScript
License
Apache-2.0
分支
dev
deepseek-harnessdshdsh-pluginweb-ui

安装

$ dsh plugin --profile web add github:zhu1090093659/dsh-web-ui/packages/skins/skin-center

在终端中运行以上命令,通过 dsh CLI 安装此插件。可在右上角切换 Profile。 第一次用 dsh?看这篇新手教程

一句话定位

dsh 网页端的皮肤中心,把皮肤列表、试穿、应用做进设置里的一级页面,并作为插件市场唯一的皮肤加载器与渲染器。它既能切换内置皮肤主题,也能让你把本地视频或 Wallpaper Engine 壁纸直接铺到聊天窗口后面。

核心能力

  • 在设置里集中管理皮肤:内置 15 款皮肤(蓝色幻想、赛博夜城、初音未来、Minecraft、芙宁娜、Windows XP Luna 等)加上放进 $DSH_HOME/skins/<id>/ 的用户皮肤同台展示,当前应用目标带「使用中」标记。
  • 原子切换引擎:试穿与应用共用一套切换逻辑,切换是浏览器侧的事,不刷新页面、不改写 cordis.patch.yml、不重建启动图;最新请求永远胜出,失败或被淘汰的请求会完整保留上一套皮肤。
  • 防闪屏首屏:host 半区在 webServer.tapIndex 注册一个适配模块,向每份 index.htmlhtml[data-dsh-skin] 并注入样式表链接,刷新后直接以当前皮肤启动;任何异常都 fail-closed 回退到官方原貌。
  • 主页背景控制:背景遮罩滑杆(0–100%)与两枚按状态的高斯模糊滑杆(0–20 px)独立调节,0 时不渲染元素、不消耗 GPU;只对画了背景的皮肤生效,官方默认不受影响。
  • Wallpaper Engine 桥接:自动定位 Steam 安装(仅 Windows),扫描项目与创意工坊内容;macOS / Linux 可添加手动文件夹(单项目目录、项目合集或纯 .mp4/.webm 文件夹),~ 展开为主目录。视频用 <video> 渲染,web 壁纸用沙箱 <iframe>,场景壁纸经内置 WebGL 播放器实时回放。
  • 旧版迁移兼容:升级到 v2 后首次启动会自动读取已退役的 dsh-skin 受管段,把当前皮肤 id 迁进新存储并清除旧行,迁移幂等且 fail-closed。

技术实现

  • 语言: TypeScript + React 18(jsx: react-jsx,target es2024)
  • 关键依赖: @deepseek-ai/cordis(插件运行时)、@deepseek-ai/dsh-client-runtime / dsh-client-locale / dsh-client-ui-theme / dsh-client-ui-settings(浏览器半区 SDK)、lightningcss(host 侧 CSS 安全管线,含 native binding)、schemastery(设置命名空间的 Schema 定义)
  • 架构模式: cordis bundle 双半区包,src/index.ts 是 host 半区(注册 /api/skin-center/v2/*/api/skin-center/we/* 路由、tapIndex 适配器、一次性的 v1→v2 迁移桥),src/client/index.ts 是浏览器半区(注册一级 settings.section、运行 effect ledger、原子切换控制器、语义适配器、Wallpaper Engine 桥)。所有官方 DSH 耦合由皮肤中心吸收,皮肤作者只对 contracts/ 契约负责。
  • 入口文件: src/index.ts(host apply)+ src/client/index.ts(browser apply);皮肤作者契约为 contracts/skin-manifest-v2.schema.json + contracts/hooks-api.d.ts + contracts/semantic-attrs-v1.md;CSS 安全管线入口为 src/core/css-safety/transform.ts

适用场景

觉得 dsh 网页端的浅色/深色官方原貌不够个性、想换一套配色或加点插画背景的人:内置 15 款皮肤覆盖二次元、像素风、商务、海港、XP 复古等常见偏好。如果你已经在用 Wallpaper Engine,把 Steam 库里的视频/网页/场景壁纸直接铺到聊天窗口后面,免去再开一层桌面壁纸。开发者想给团队定制一套专属皮肤,只需要按 contracts/ 的 v2 契约丢一个目录到 $DSH_HOME/skins/,就能进卡片列表被使用。

前置依赖与兼容性

依赖最低版本说明
@deepseek-ai/dsh-*^0.1.0-rc.8host/client 半区都通过 SDK 注入服务;皮肤中心把对官方 DSH 的耦合吸收在契约之后
React^18.2.0peerDependency,浏览器半区 SkinCenter.tsx 使用 React hooks
Node^22.19 || >=24仓库根 AGENTS.md 强制要求;package.json 未声明 engines,但 host 侧使用 node:fs / node:child_process / node:os
平台跨平台皮肤切换、用户皮肤目录、手动壁纸目录都跨平台;Wallpaper Engine 自动发现仅支持 Windows(注册表 + libraryfolders.vdf),macOS/Linux 通过「手动文件夹」兜底
原生模块lightningcsshost 侧 CSS 安全管线;已显式 external 在 tsdown.config.ts,不出现在浏览器 bundle

安装方式

dsh plugin --profile web add github:zhu1090093659/dsh-web-ui/packages/skins/skin-center

配置项

配置类型说明默认值
skin-background.enabledboolean整张皮肤中心卡片总开关;关闭后停用试穿、应用、背景控制true
skin-background.backgroundOpacity0–100主页背景遮罩强度(仅作用于画背景的皮肤)0
skin-background.backgroundBlurEmpty0–20 px空对话状态下的高斯模糊半径0
skin-background.backgroundBlurContent0–20 px有对话内容时的高斯模糊半径0
skin-wallpaper.enabledbooleanWallpaper Engine 桥的总开关true
skin-wallpaper.weLibraryDirsstring[]手动壁纸库目录列表(每个是项目文件夹、项目合集或纯媒体文件夹)[]
skin-wallpaper.selectionstring当前应用的壁纸 id(空字符串 = 不应用)""
skin-wallpaper.mode'live' | 'frame'实时播放或钉一张静态帧'live'
skin-wallpaper.pauseOnHiddenboolean窗口隐藏时暂停视频,节省 GPUtrue
skin-wallpaper.dim0–90壁纸之上的压暗层百分比25
skin-wallpaper.wallpaperBlur0–60 px壁纸本身的高斯模糊半径0
skin-wallpaper.fit'cover' | 'contain' | 'fill'实时壁纸的填充方式'cover'
$DSH_HOME / ~/.dsh路径DSH 主目录根,用于皮肤目录、当前选择状态、迁移桥~/.dsh
$DSH_SKINS_HOME路径覆盖用户皮肤目录根,开发与测试用未设置
$DSH_HOME / $DSH_SKIN_PROFILE / $DSH_PROFILE环境变量决定迁移桥读写哪个 profile 的 cordis.patch.yml默认 profile=web

常见问题

Q: 安装完为什么设置里看不到皮肤中心?

A: 皮肤中心以一级 settings.section 形式挂载在「设置」里,需要刷新页面并打开「设置」才能看到「皮肤中心」入口。卡片默认开启(SkinBackgroundConfigSchema.enabled 默认 true),打开后立即列出所有内置与用户皮肤。

Q: 切换皮肤需要重启 DSH 吗?

A: 不需要。皮肤切换完全在浏览器侧完成(src/client/runtime/skin-controller.ts),不刷新页面、不重写 cordis.patch.yml、不重建启动图。首屏由 tapIndex 适配器预先盖好 html[data-dsh-skin] 并注入样式表链接,刷新后直接以当前皮肤启动,没有官方原貌闪屏。

Q: 用户自己做的皮肤怎么放进去?

A: 把符合 v2 契约(contracts/README.md)的皮肤目录丢进 $DSH_HOME/skins/<id>/DSH_SKINS_HOME 环境变量可改根目录),重开卡片或刷新页面就会出现在列表里。同 id 的用户皮肤会遮蔽内置皮肤;skin.json 校验失败会被 fail-closed 排除并在目录诊断里给出原因。

Q: 试穿和应用有什么区别?

A: 两者走同一个原子切换引擎(src/client/runtime/skin-controller.ts),区别只在是否落盘:试穿不持久化,「退出试穿」恢复到上次应用的状态;应用会调用 POST /api/skin-center/v2/active,把选择写到 $DSH_HOME/skin-center-active.json

Q: macOS / Linux 上能用 Wallpaper Engine 吗?

A: Wallpaper Engine 自动发现仅支持 Windows(通过 Windows 注册表读 SteamPathsrc/we-library.ts:145)。macOS 和 Linux 可在卡片「手动文件夹」行添加任意 .mp4/.webm 文件夹、单项目目录或项目合集目录作为媒体库,路径中的 ~ 会展开为主目录。

Q: 自定义皮肤的 hooks.mjs 有什么风险?

A: hooks.mjs 是受信代码逃逸舱(contracts/README.md 安全模型节),与本仓库同审同发,仅同源 serve。它拥有完整 DOM 与样式能力,导入或执行错误被 try/catch 隔离但不会拖垮静态皮肤——只在你信任该皮肤的作者时使用。

Q: 怎么临时关掉皮肤中心?

A: 卡片自带总开关(SkinBackgroundConfigSchema.enabled),关闭后会停用试穿、应用、背景控制,持久化在 skin-background 命名空间。壁纸部分另有独立的总开关(SkinWallpaperConfigSchema.enabled),持久化在 skin-wallpaper 命名空间。彻底卸载用 dsh plugin --profile web remove @linxin666/dsh-client-ui-skin-center

Q: 自定义皮肤会被上传或外发吗?

A: 不会。所有 /api/skin-center/* 路由同源服务,写操作通过 Sec-Fetch-Site / Origin 围栏拦截跨站请求;皮肤 CSS 在服务前经白名单净化(src/core/css-safety/transform.ts)。壁纸导入仅复制到本机 harness-home 目录,从不上传或再分发,创意工坊内容归原作者所有。

上手难度

入门 — 装好后在设置里点开皮肤中心就能立即试用,一键应用即生效;如果只想用内置皮肤,零配置门槛。

已知问题与限制

  • 插件运行时通过 inline style 写入的样式只能经 L3 patches.css!important 覆盖(README.md:43)。
  • 不输出语义属性(data-dsh-surface / data-dsh-part / data-dsh-plugin,枚举见 contracts/semantic-attrs-v1.md)且无稳定 DOM 锚点的插件只享受 L1 token 基础覆盖,无法获得完整换肤(README.md:44)。
  • 皮肤的视频背景不受壁纸「隐藏时暂停」设置影响;该设置仅作用于 Wallpaper Engine 桥(README.md:45)。
  • 语义适配器依赖的官方 shell 锚点(三列容器本体、侧栏导航 list slot、设置模态专属标识)目前缺少稳定选择器,作者已在 contracts/semantic-attrs-v1.md 列出对上游主题缝 PR 的四点诉求。
  • patches.css(L3)按设计就是任意 CSS,与 hooks.mjs 一样被官方明确告知为高敏感、不是安全边界(README.md:38-39)。