# deepseek-harness-desktop

> 在 DSH Web GUI 设置里嵌入皮肤中心卡片，列出全部已装皮肤并支持 GUI 内即时试穿与一键应用，无需复制命令或重启。

## Metadata

- Author: [@ningbainb](https://github.com/ningbainb)
- Repo: <https://github.com/ningbainb/deepseek-harness-desktop.git>
- GitHub: [ningbainb/deepseek-harness-desktop](https://github.com/ningbainb/deepseek-harness-desktop)
- Stars: 156
- Language: TypeScript
- License: [BSD-3-Clause](https://spdx.org/licenses/BSD-3-Clause.html)
- Homepage: <https://ningbainb.github.io/deepseek-harness-desktop/>
- Topics: `ai-agent`, `ai-coding-assistant`, `codex`, `deepseek`, `deepseek-harness`, `desktop-app`, `dsh`, `dsh-plugin`, `electron`, `electron-app`, `gui`, `open-source`, `plugin-system`, `plugins`, `remote-access`, `skills`, `ssh-client`, `windows`, `windows-desktop`
- Forks: 5
- Open Issues: 6
- Last push: 2026-08-20T05:29:52.000Z
- Added: 2026-08-20T00:00:00.000Z

## Install

```bash
dsh plugin --profile web add github:ningbainb/deepseek-harness-desktop/packages/skins/skin-center
```

## Wiki

## 一句话定位
在 DSH Web GUI 的「Web UI 插件」分组里嵌入一张「皮肤中心」卡片，把已安装皮肤做成可在浏览器里即时试穿、并一键应用到当前 profile 的可视化面板，省去复制终端命令和重启服务。

## 核心能力
- 在「设置 → 插件配置 → Web UI 插件」里添加一张「皮肤中心」卡片，与 task-board、pet 等共用同一槽位（`web-ui.plugin.item`），不占设置一级导航。
- 自动列出当前 profile 下已安装的全部皮肤（含官方默认），每个皮肤卡片显示名称、tagline 和强调色色块；当前激活的皮肤带「Active」标识。
- GUI 内实时试穿：点"试穿"后按需加载该皮肤的 client bundle，立即看到效果，支持亮/暗主题切换预览；"退出试穿"会完整还原试穿前的视觉状态（body 属性、背景样式、皮肤 chrome 子节点等都被快照并在退出时原样恢复）。
- 一键应用：点击"应用"或"恢复默认"会调用 host 端 `/api/skin-center/apply`，由 host 进程内嵌的 `dsh-skin use` 移植版把当前选择写入 `<harness-home>/profiles/<profile>/cordis.patch.yml`，DSH 配置 watcher 在数秒内热载入并自动刷新页面，整个过程无需手动复制命令、无需 `dsh web` 重启。
- 主题预览与背景遮挡：卡片内置亮/暗主题切换控件，以及 0–100% 的背景遮挡滑杆（仅对带背景图插画的皮肤生效，官方默认不受影响）。
- 失败兜底：apply 接口返回错误时，UI 上会附带 `dsh-skin use <name>` / `dsh-skin use official` 的终端兜底命令。

## 技术实现
- **语言**: 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` / `dsh-client-ui-slots` / `dsh-settings`（浏览器与 host 半区 SDK），`schemastery`（设置命名空间 Schema 校验），`react ^18.2.0` 作为 peerDependency
- **架构模式**: cordis bundle 双半区包，符合 DSH 官方 bundle 形态；`src/index.ts` 是 host 半区（注册 `/api/skin-center/*` HTTP 路由、把"皮肤中心"卡片挂到「Web UI 插件」分组），`src/client/` 是浏览器半区（卡片组件 + 试穿引擎 + 背景控制器 + i18n 字典），共享纯逻辑放在 `src/` 根目录（`skin-switch.ts` 为 host 进程内嵌的 `dsh-skin use`/`current` 移植版）
- **入口文件**: host 入口 `src/index.ts`（apply 注册路由）、浏览器入口 `src/client/index.ts`（apply 注册卡片与字典）；cordis 插件 id 为 `ui-skin-center`，对应 `cordis.patch.yml` 中插入的 insert 行

## 适用场景
希望快速试用或切换皮肤、不想在终端手动执行 `dsh-skin use` 又担心命令拼错的 DSH Web GUI 用户。当官方原貌不够个性、想立刻对比几款皮肤效果时，皮肤中心可以在不重启服务的前提下实时试穿，决定后一键落盘。对于已装多个皮肤的 profile，皮肤中心还解决了"如何用一个面板统一管理它们"的问题。

## 前置依赖与兼容性
| 依赖 | 最低版本 | 说明 |
|---|---|---|
| @deepseek-ai/dsh-* | ^0.1.0-rc.7 | host 与 client 半区都通过官方 NPM SDK 注入服务；package.json 未单独声明 dsh_version，devDependencies 中所有 @deepseek-ai/dsh-* 均为此版本 |
| @deepseek-ai/cordis | ^4.0.1 | 插件运行时 |
| React | ^18.2.0 | peerDependency，浏览器卡片组件使用 React hooks |
| Node | ^22.19 \|\| >=24 | 仓库 packages/AGENTS.md 强制要求；package.json 未声明 engines |
| 平台 | 跨平台 | 皮肤切换逻辑与 GUI 卡片均跨平台；Windows 下 profile 链接在 symlink 权限不足时自动回退为目录 junction，不需要开发者模式 |
| 原生模块 | 无 | package.json dependencies 仅含 schemastery（纯 ESM），无需 native binding |

## 安装方式
```bash
dsh plugin --profile web add github:ningbainb/deepseek-harness-desktop/packages/skins/skin-center
```

## 配置项
| 配置 | 类型 | 说明 | 默认值 |
|---|---|---|---|
| skin-background.backgroundOpacity | 0–100（步长 5） | 主页背景遮挡强度；仅对带背景图插画的皮肤生效，官方默认无背景图不受影响 | 0 |
| ~/.dsh / $DSH_HOME | 路径 | DSH 主目录，决定 host 写入哪个 profile 的 cordis.patch.yml 与 node_modules 链接 | ~/.dsh |
| $DSH_SKIN_PROFILE / $DSH_PROFILE / process.cwd() 位于 profiles/ 下 | profile 名 | 决定 host 端写入的目标 profile（依次取显式 option → DSH_SKIN_PROFILE → DSH_PROFILE → cwd → 默认 web） | web |

## 常见问题

**Q: 装完后在哪里打开皮肤中心？**

A: 装好后需要刷新一次 DSH Web GUI 页面，然后进入「设置 → 插件配置 → Web UI 插件」分组，里面会多出一张名为「皮肤中心 / Skin Center」的折叠卡片。卡片与 task-board、pet、live-stats 共用同一个槽位（`web-ui.plugin.item`），不会占设置页的一级导航。

**Q: 切换皮肤要重启 DSH web 吗？**

A: 不需要。整个流程是：UI 调用 `/api/skin-center/apply` → host 进程内嵌的 `dsh-skin use` 移植版把当前选择写入 `<harness-home>/profiles/<profile>/cordis.patch.yml` → DSH 配置 watcher 在数秒内热载入 → 页面自动刷新进入新皮肤。这一切都在 host 进程内完成，无需 `dsh web` 重启，也不要求 PATH 上有 `dsh-skin` 二进制。

**Q: "试穿"和"应用"有什么区别？**

A: 试穿只在浏览器里临时加载皮肤 bundle 到当前页面，刷新或重启后失效；应用会调用 host 的 `/api/skin-center/apply`，由 host 端把选择落盘到 profile patch 并迁移旧的全局 `dsh-skin managed` 段（如果存在）。简单说：试穿是"看一眼效果"，应用是"真的换上"。

**Q: 为什么皮肤列表里没有某些皮肤？**

A: 皮肤中心只列出当前 profile 下已安装的皮肤包。每个皮肤是独立的 npm 包（如 `@linxin666/dsh-client-ui-skin-qq98`），需要先单独安装，或通过全家桶聚合包 `@linxin666/dsh-skins` 一次装齐。安装后刷新页面，列表会自动更新。

**Q: 应用失败时怎么兜底？**

A: apply 接口返回错误时，UI 上会显示一段提示，里面附带可手动执行的命令：`dsh-skin use <皮肤id>`（如 `dsh-skin use blue-fantasy`）或 `dsh-skin use official`（恢复官方默认）。在终端里执行同样的命令可以达到相同效果。

**Q: 怎么彻底卸载？**

A: 在终端执行 `dsh plugin --profile web remove @linxin666/dsh-client-ui-skin-center` 即可，DSH 插件管理器会负责清理 profile 里的相关条目。皮肤中心本身只管理 `dsh-skin managed` 段，不会影响其他插件；卸载后该段也会一并清空。

**Q: 在 Windows 上会有兼容问题吗？**

A: 一般不会。profile 的 node_modules 链接在 symlink 权限不足时会自动回退为目录 junction（绝对路径），不需要开发者模式或管理员权限。皮肤切换、试穿、背景遮挡等纯浏览器逻辑完全跨平台。

## 上手难度
入门 — 装好后在 GUI 内点开「皮肤中心」卡片就能立即试用所有已装皮肤，"应用"一键落盘自动刷新，无需任何额外配置。

## 已知问题与限制
- pnpm ≥10 安装 git 依赖前需要先授权 `allowBuilds`（`prepare` 脚本会原地构建），本地 link 安装则没有这个限制（README.md:30）。
- 本地 link 安装前需要在 monorepo 内先构建（`pnpm install && pnpm -r build`），因为 `lib/` 被 git 忽略、不随仓库提交（README.md:28）。
- 皮肤中心只列出当前 profile 已安装的皮肤，要试穿更多皮肤必须先把对应的 npm 包装到 profile 中；皮肤中心本身没有自带互斥要求（README.md:32）。
- 从老版本 Desktop 2.2/2.3 升级时，如果 `<harness-home>/cordis.patch.yml` 里残留有 `dsh-skin managed` 段，首次 apply 会把它迁移到当前 profile 的 patch 并从全局文件移除（src/skin-switch.ts:964-972），属于一次性迁移行为。
- Windows 下符号链接权限不足时回退为目录 junction，是已知降级行为而不是 bug（src/skin-switch.ts:765-799）。

---

This document is auto-generated by [deepseek-plugin.org](https://deepseek-plugin.org). HTML page: [deepseek-harness-desktop](https://deepseek-plugin.org/plugins/ningbainb/deepseek-harness-desktop/packages/skins/skin-center)
Wiki generated by AI (model: `MiniMax-M3`)
