一个给 DeepSeek Harness(DSH)Web GUI 用的视觉皮肤插件:把 Codex Dream Skin 项目的 INTERNET ANGEL 美术方向完整移植到 DSH 的 Web 界面上。
| 暗色主题 | 浅色主题 |
|---|---|
![]() |
![]() |
零 API Key · 零网络请求 · 纯前端渲染 · 卸载即还原
dsh-my-plugin 是一个标准的 DSH bundle 插件:通过 cordis.patch.yml 把自己的
client 入口插入 DSH Web 的插件名册,随后在浏览器里注入一份样式表并给 <body>
打上 data-dsh-dream-skin 标记,界面立刻切换为「超天酱 · INTERNET ANGEL」主题。
设计上刻意保持克制:
- 不接管任何原生功能。聊天框、侧栏、设置、快捷键、拖拽、流式输出全部保持原样, 插件只做「重新上色 + 绘制装饰」,不改布局、不拦截指针事件。
- 不注入 React 节点。背景直接画在
body上,装饰件带aria-hidden, 永远不会和 React 争夺 DOM 所有权。 - 可完整回滚。所有写入(样式表、body 属性、标题、
theme-color、装饰节点) 都由 Cordis effect disposer 逐项撤销,禁用/卸载插件后界面逐像素还原。
| 特性 | 说明 |
|---|---|
| 主视觉背景 | INTERNET ANGEL 插画铺满视口,fixed 定位不随滚动跳动;主体锚定右侧(focus 72% / 42%),左侧留出低信息量的安全阅读区 |
| 双向渐变蒙版 | 横向 + 纵向两层渐变压暗,保证任何窗口宽度下正文文字都有足够对比度 |
| 品红霓虹配色 | 品牌色 #ff45c8,通过重映射 --dsw-* 别名 token 让所有面板一次性获得半透明品红质感 |
| 暗色 / 浅色双调色板 | 自动跟随 DSH 主题信号(body[data-ds-dark-theme]),无需手动切换 |
| 系统 chrome 联动 | 同步 <meta name="theme-color">,浏览器/移动端状态栏与皮肤同色 |
- Composer「HUD 甲板」:输入框被重绘成切角(chamfer)面板 —— 三角直角、右上角 18px 斜切, 斜边用描边补线;外圈再加一层错位副甲板,形成双层悬浮观感。
- 扫描线质感:面板内叠加水平扫描线(alpha
0.04),近乎不可察但能消除大色块的塑料感。 - 聚焦呼吸光:输入框获得焦点时出现品红边缘辉光 + 2.6s 呼吸动画。
- 发送按钮状态:草稿为空时是暗描边;一旦有输入立刻点亮为渐变光块 + 边缘辉光。
- 控件重制:
+/ 附件按钮统一为 24px 圆角方块,composer 图标等比缩小。 - 消息气泡:为暗色与浅色两套面板分别重新调色,规则中不添加真实
border,避免改变盒模型。 - 侧栏品牌层:侧栏顶部注入
CODEX // INTERNET ANGEL ♥+ 标语 +STREAM ONLINE状态行,带微光动画。 - 标题栏品牌层:标题栏左侧注入品牌副标题与
BLESS YOUR CODE ♥。 - 滚动条:细长品红滚动条,跨浏览器一致。
prefers-reduced-motion: reduce下关闭全部呼吸/微光动画。- 所有注入装饰节点都带
aria-hidden="true",不进入无障碍树。 - 装饰性状态文案只是视觉元素,不会覆盖原生语义标签。
- 不读凭据、不发网络请求、不读写任何 API Key。整个插件只有一份内联样式表和一个 DOM 观察器(用于 React 换帧后重新安置装饰件)。
- 插画的 JPEG 在构建期以 data URI 内联进
lib/client.js,运行时零外部资源请求, 离线环境同样正常显示。
下面是插件在真实 DSH Web GUI 中的实际运行效果,同一个界面分别处于暗色与浅色主题 —— 两套调色板都由宿主主题信号自动切换,无需任何配置。
- 主视觉插画铺满视口,主体(超天酱)锚定右侧,左侧留出低信息量的安全阅读区,正文对比度不受影响。
- 侧栏整体转为半透明深紫,与插画自然融合;输入框呈现切角 HUD 甲板 + 品红描边。
- 右上角标题栏是注入的品牌层
CODEX // INTERNET ANGEL ♥ — BLESS YOUR CODE ♥。
- 同一套布局切换为浅色粉白调色板,面板依旧半透明,插画透出但不抢文字。
- 品红主色在浅色下改为低饱和描边,保证浅底上的可读性。
上图由 scripts/render-preview.mjs 渲染,用于在不重启 DSH 的情况下审查几何与配色:
上下两块分别是 未聚焦 / 空草稿(发送键暗)与 聚焦 / 有草稿(发送键点亮)状态。
前置条件:Node.js ≥ 20 与 pnpm 已在
PATH上(dsh plugin是 pnpm 的转发器)。
无需克隆仓库,一条命令:
dsh plugin --profile web add github:NoMindSama/dsh-my-plugindsh plugin会把参数转发给 pnpm,装完后自动把包名dsh-my-plugin追加进dsh.profile.bundles,成为 profile 的一个层。- 本仓库已提交构建产物
lib/client.js,包内没有prepare脚本, 因此不会触发 pnpm 的构建脚本拦截,安装即用。 - 装完后重启
dsh web,再按F5刷新浏览器。
git clone https://github.com/NoMindSama/dsh-my-plugin.git
cd dsh-my-plugin
dsh plugin --profile web add link:.link:. 表示链接当前目录(仓库根目录本身就是插件包)。若仓库被复制到别处,用绝对路径:
dsh plugin --profile web add link:E:\你的路径\dsh-my-plugin
⚠️ 不要写成link:.\dsh-my-plugin—— 仓库里没有这个子目录,那样会被当成普通依赖安装, 重启后皮肤不会生效。
在目标 profile 的 package.json(例如 %USERPROFILE%\.dsh\profiles\web\package.json)里:
然后在该 profile 目录执行 pnpm install 并重启 dsh web。
需要代理时,先设置环境变量再执行安装:
$env:http_proxy="http://<ip>:<port>"; $env:https_proxy="http://<ip>:<port>"; $env:all_proxy="socks5://<ip>:<port>"
dsh plugin --profile web add github:NoMindSama/dsh-my-plugin-
更新:
dsh plugin --profile web update dsh-my-plugin -
共存:本插件是「皮肤」而不是「组件」,同时启用多个皮肤会互相覆盖样式。 请只保留一个皮肤的
enabled(见下节),或用 DSH 的 skin manager 插件切换。 -
若同一 profile 里同时装了多个皮肤 bundle,在 profile 的
cordis.patch.yml里禁用其余皮肤:- id: dsh-my-plugin disabled: false - id: 其它皮肤-id disabled: true
本插件不包含任何 API Key / Token / 账号配置项,也从不发起网络请求。 它纯粹是浏览器端的样式层,装完即生效,无需填写任何密钥。
也就是说:安装后你不需要做任何配置。下面各项都是可选的外观微调。
皮肤的所有设计常量都集中在两个地方,改完需要重新构建(见下节):
| 想改什么 | 改哪里 |
|---|---|
品牌色(品红 #ff45c8) |
src/client.template.js 里的 const ACCENT,以及 assets/theme.json 的 palette.accent |
| 主视觉焦点位置 | src/client.template.js 的 const BG_POSITION(如 "72% 42%")与 assets/theme.json 的 art.focusX / focusY |
| 浏览器标题 | src/client.template.js 的 const WINDOW_TITLE |
| 侧栏品牌三行文案 | const BRAND_SUBTITLE / const TAGLINE / const STATUS_TEXT |
| 标题栏引语 | const QUOTE |
| body 标记属性 | const BODY_ATTR(同时要改 skin.json 的 bodyAttr) |
| 换一张主视觉插画 | 替换 assets/dream-reference.jpg(必须是 JPEG,构建脚本会校验 magic bytes) |
跟随 DSH 自身的主题设置即可 —— 皮肤同时提供两套调色板,会随 data-ds-dark-theme
信号切换,没有独立开关。
系统开启「减少动态效果」后,呼吸与微光动画自动停止,无需配置。
dsh plugin --profile web remove dsh-my-plugin然后重启 dsh web 并刷新浏览器。卸载/禁用后插件会逐项回滚:样式表移除、body
属性释放、页面标题与 theme-color 还原、注入的品牌节点删除。
# 1) 改完 src/client.template.js 后,把插画内联进 lib/client.js(唯一会写 lib 的脚本)
node scripts/build-asset.mjs
# 2) 结构 + 行为校验:61 项检查,覆盖注册契约、样式规则约束、激活与完整回滚
node scripts/verify-skin.mjs
# 3) 发布校验:证明运行时只需 5 个文件即可独立跑起来
node scripts/verify-standalone.mjs
# 4) 渲染 composer 设计预览(需要 sharp)
node scripts/render-preview.mjs assets/preview-composer.pnglib/client.js 是生成产物,请勿直接编辑 —— 它由 src/client.template.js
加上内联插画生成。
dsh-my-plugin/
├── package.json # DSH bundle 元数据(dsh.bundle.patch / dsh.client)
├── cordis.patch.yml # 把本插件的 client 入口插入 Web 插件名册
├── skin.json # 皮肤自描述元数据(名称、主题标签、兼容版本)
├── README.md
├── LICENSE
├── lib/
│ ├── index.js # 宿主侧入口(浏览器皮肤,宿主侧无行为)
│ └── client.js # 生成的浏览器 bundle(含内联插画 data URI)
├── src/
│ └── client.template.js # 皮肤源码(样式、品牌层、生命周期)
├── scripts/
│ ├── build-asset.mjs # 内联 assets/dream-reference.jpg → lib/client.js
│ ├── verify-skin.mjs # DOM stub 下跑真实 bundle,61 项检查
│ ├── verify-standalone.mjs # 运行时最小文件集校验
│ └── render-preview.mjs # 渲染 composer 设计预览图
└── assets/
├── dream-reference.jpg # 主视觉插画(构建期内联)
├── theme.json # 主题预设描述
├── screenshot-dark.png # README 实拍图(暗色)
├── screenshot-light.png # README 实拍图(浅色)
└── preview-composer.png # composer 设计稿渲染图
运行时实际只加载 5 个文件:package.json、cordis.patch.yml、skin.json、
lib/index.js、lib/client.js。
- 目标 DSH 版本:0.1.5-rc.1(
skin.json的dshCompatibility字段)。 - DOM 锚点已按该版本核对:
[class*='sidebarCol']/[class*='centerCol']、[data-composer-card]、[data-phase='hero'|'active']、[data-chat-flow]、[data-conversation-scroll]、body[data-ds-dark-theme]。 - 宿主升级后若界面锚点改名,装饰层可能不再就位(样式本身仍会生效)。
此时优先跑一次
node scripts/verify-skin.mjs定位失效的选择器。
Q:装完了但界面没变化?
按顺序检查:① 是否重启了 dsh web;② 浏览器是否 F5 强刷(Ctrl + F5);
③ 插件是否真的进了 dsh.profile.bundles(检查 profile 的 package.json);
④ cordis.patch.yml 里是否被 disabled: true 关掉了。
Q:提示 pnpm not found on PATH?
先安装 pnpm(npm i -g pnpm)再重试;dsh plugin 只是 pnpm 的转发器。
Q:link:. 装完重启后没反应?
大概率是把 link:.\dsh-my-plugin 写成了子目录路径,或安装后又移动了源码目录。
先 dsh plugin --profile web remove dsh-my-plugin,再用正确的绝对路径重新 add。
Q:多个皮肤打架?
皮肤之间是互斥的。用 skin manager 切换,或在 profile 的 cordis.patch.yml 里把其余皮肤
disabled: true。
Q:会影响聊天、上传、快捷键吗?
不会。插件不接管事件、不改布局,只重绘外观;所有规则都避免触碰 position/size/指针事件。
- 美术方向来自 Codex Dream Skin 项目(
EmiyaKatuz/Codex-Dream-Skin)的windows/assets/theme.json,本插件为 从零适配 DSH WebUI 的移植实现。 - 插画版权归原作者所有,本仓库仅作主题演示用途;如需商用请自行确认授权。
License: MIT —— 见 LICENSE。




{ "dependencies": { "dsh-my-plugin": "link:E:/你的路径/dsh-my-plugin" }, "dsh": { "profile": { // 追加到层列表末尾;皮肤之间互斥由 skin manager 或 cordis.patch.yml 的 disabled 控制 "bundles": ["...", "dsh-my-plugin"] } } }