DSH Plugins Marketplace

DSH Plugins

Plugins

/

UI & Experience

/

dsh-desktop-acrylic

L

dsh-desktop-acrylic

Manifest valid★ 1

Tokyo Night 暗色 / 亮色主题 for DeepSeek Harness (DSH) 桌面端 —— 注册进主题运行时的真实皮肤,含亚克力磨砂面板、材质模糊与等宽字体选择器。Tokyo Night dark & light themes for DeepSeek Harness (DSH) Desktop — real theme-runtime skins with acrylic panels, material blur, and a monospace font picker.

UI (client)hasBundlePatch

dsh-desktop-acrylic

中文 · English

Tokyo Night themes for DeepSeek Harness (DSH) Desktop — 两套主题(暗色 / 亮色)、磨砂面板、等宽字体选择。

两套皮肤都是注册进内置主题运行时的真实主题(ctx.theme.register),因此切换主题就是切换 运行时偏好本身,不依赖属性开关或事后 CSS 覆盖。

DSH Desktop 测试版下载:deepseek-harness 讨论区。

若你在论文、报告或其它项目中使用本项目,请引用它 —— 引用模板见引用与许可, 仓库根目录也提供了机器可读的 CITATION.cff(GitHub 会据此显示 "Cite this repository")。

效果预览

暗色 —— 欢迎页:

Tokyo Night 暗色主题(欢迎页)

亮色 —— 欢迎页:

Tokyo Night 亮色主题(欢迎页)

设置窗口 —— 磨砂面板与背景遮罩模糊(暗色;可见「Tokyo Night 主题」设置行与 masks 1 诊断):

设置窗口:磨砂面板 + 背景遮罩模糊


能力一览

能力实现方式参数
主题:Tokyo Night 暗色 / 亮色皮肤 token(静态色阶 + 别名色阶 + 组件专属 + 语法高亮),两套各 410 个 token暗色底#1a1b26;亮色底偏白(#e7e8ee → #eff1f6 一族)
图标随主题变色桌面端用currentColor 绘制图标且没有图标专属 token,因此图标自动跟随 --dsw-alias-label-* / --dsw-alias-brand-primary无需额外配置
画布透明度背景族 token 带 alpha,按可读性求解(见下)暗色0.73;亮色 0.30(均为白底合成后 ≥ 4.5:1)
材质底层用主题自身的蓝/紫/青做的柔和色场,固定在最底层并预模糊强度 暗 30% / 亮 24%,blur(28px)
弹出菜单 / 下拉 / 浮层皮肤下发--dsw-menu-backdrop-filter,由桌面端自带材质通路渲染blur(24px) saturate(1.15)
对话框(设置窗口等)磨砂面板:定位元素走 isolation + 绝对定位 ::before;静态元素(设置窗口常见)改把模糊直接加在元素上,但先排除含 position: fixed 后代的对话框底色rgba(…, 0.75)(25% 透明)+ blur(30px)
对话框背景遮罩弹窗背后压暗页面的遮罩挂 backdrop-filter,透出磨砂主界面;原生 <dialog> 走 ::backdrop;prefers-reduced-transparency 时随模糊层一并停用blur(12px) saturate(1.1)(--dwa-mask-blur)
工作区主侧栏均匀颗粒纹理(纯background-image,无方向性、无边缘)暗色 6% / 亮色 14%(明暗感知不对称,故分开设值)
卡片与表格(genui)把卡片库自带的--tv-* 调色板桥接到我们的别名 token249 条桥接,覆盖卡片库引用的全部 --tv-color-* 名称
原生控件color-scheme 随主题切换滚动条、复选框等原生部件一并跟随
字体两个可搜索下拉(界面字体 / 代码字体),列出本机可用的等宽字体(含 NF / PL 变体)见下文「字体探测」

集中定义:src/theme.mjs 的 ACRYLIC(模糊半径等)、surfaceTable(表面与 alpha)、 MONO_FONTS / MONO_FONT_BASES / MONO_FONT_SUFFIXES(字体数据);样式规则由构建脚本生成。

背景(材质场)与可读性的平衡

材质场是这套主题的「背景」:三团柔和色斑 + 一层带色相的渐变,画在 body 与 body::before 上,预模糊 28px。 表面越不透明,它就越看不见——这就是「背景怎么没了」的机制。

0.9.8 的最终取值(此前两次调整都过头了,这里定下来):

角色值说明
材质强度暗色 38% / 亮色 30%原来是 30 / 24;色斑半径也放大一档(55/50/60),底层渐变掺 10% 主色相
地色root 0.84 / 画布 72%决定整体明度,也决定「样式表没挂上」时的下限
大面积表面暗色 0.32–0.48画布 0.34、层 1 与侧栏 0.32、层 2 0.40、层 3 0.48 → 材质透过率约 2/3
亮色表面原值不动0.30 / 0.24 / 0.72 等;实测单独过白底就有 8.9:1,没有理由抬
硬下限alpha ≥ 0.32只有「会读成一个洞」的表面才被抬到这条线

可读性实测(两个最坏情况都算过):

  • 组合路径(根 → 画布 → 表面):8.0–10.4:1,远高于 AA。
  • 材质最强处(色斑最亮的一像素,文字直接压上去):暗色 4.57:1、亮色 5.24:1;再叠加表面后最差 5.50:1 / 5.92:1。
  • 降级路径(只剩 token、样式表没挂上):单独过白底 1.30–1.59:1——不再宣称 AA,靠硬下限保证「不是洞」。

构建守卫:alpha < 0.32 且单独过白底 < 1.6:1 → 判为洞,exit 1;组合后 < 6:1 同样 exit 1。 守卫常量写死在 scripts/build.mjs(GUARD_*),刻意不从 theme.mjs 读——否则调旋钮会顺手把守卫关掉。

安装

# 从 GitHub
dsh plugin --profile desktop add github:LeoLee0097/dsh-desktop-acrylic

# 从本地目录(-w 必需,profile 目录本身是 pnpm workspace 根)
dsh plugin --profile desktop add -w /absolute/path/to/dsh-desktop-acrylic

安装后完全退出并重启 DSH Desktop。此后单独重载渲染进程也会重新拉取客户端包。

版本兼容性

插件版本支持的 DSH说明
0.9.0+0.2.0-rc.1 及更高peer 依赖对齐 @deepseek-ai/dsh-client-* @ ^0.2.0-rc.1、@deepseek-ai/cordis @ ^4.0.4;移除已下线的 @deepseek-ai/dsh-client-runtime,改为声明实际提供服务的包(dsh-client-store / dsh-client-locale / dsh-client-ui-theme / dsh-client-ui-settings-general)
0.9.4+0.2.1-rc.2 已验证实测 DSH 0.2.1-rc.2:dsh-client-* 升到 0.2.1-rc.2,故 peer 范围改为并集 ^0.2.0-rc.1 || ^0.2.1-rc.2,两条线都接受。另移除 @deepseek-ai/dsh-client-store 的 peer 与 inject 声明:该包随运行时打包(客户端代码仍 require 它),但不在共享包清单里,声明 peer 只会得到「未知包」的误判
0.9.2+0.2.0-rc.2 已验证在 DSH 0.2.0-rc.2 上实测:全部 peer 满足(^0.2.0-rc.1 覆盖同 0.2.0 三元组的预发布版本,如 rc.2)。注意精确版本豁免是按 DSH 版本记账的:升级 DSH 后老的 exemption 全部失效,需要按新版本重新生成 compatibility.json
0.8.x 及更早0.1.0-rc.6 一线仍声明 dsh-client-runtime ^0.1.0-rc.6,在 DSH 0.2.0-rc.1 上会被插件管理器判定不兼容

若你从 0.8.x 升级到 0.9.0:拉到新版本后重启 DSH Desktop 即可,插件管理器会重新读取 peerDependencies;若仍提示不兼容,请重新执行上面的安装命令刷新 profile 的依赖记录。 本次升级不涉及任何客户端 API 变更——__ModuleLoader__、ctx.slots.inject/register、 ctx.theme.register、ctx.on('theme/change')、webServer.register({ kind: 'exact' }) 在 0.2.0-rc.1 中均保持不变(已逐一核对)。

网页端(web profile)

声明:开发者主要在 DSH Desktop 内测版中使用本插件,未在网页端进行过测试。如遇异常, 请把设置行诊断信息(preference / matched / masks 等)一并反馈。

同一插件可直接装到 web profile——桌面端本来就跑在 @deepseek-ai/dsh-web-app 上,浏览器半边 按 platform: "web" 声明,安装命令只是把 profile 换掉:

dsh plugin --profile web add github:LeoLee0097/dsh-desktop-acrylic
# 或本地目录
dsh plugin --profile web add -w /absolute/path/to/dsh-desktop-acrylic

网页端与桌面端的差异(客户端已自动降级,无需配置):

  • 持久状态:宿主路由不可用时回退 localStorage——网页端 origin 固定,这层反而比桌面端更稳;
  • 字体列表:宿主目录扫描不可用,只剩渲染进程探测(候选目录见下文「字体探测」);
  • 视觉效果一致:材质底层、磨砂面板、遮罩模糊全部在页面内完成,本来就不依赖窗口材质; 若 web 构建的 DOM 类名不同导致候选选择器失配,诊断行的 matched / masks 会如实显示 0。

安装后完全退出并重启 DSH Desktop。此后单独重载渲染进程也会重新拉取客户端包。

注意:宿主半边(lib/index.js)的改动只有重启进程才会生效,因为它的路由表在进程启动时 注册。客户端半边(lib/client.js)与数据表只需重载渲染进程。这一区别曾经导致过 「明明改了却 404」的误判,故明确写在这里。

使用

设置 → 通用 → 「Tokyo Night 主题」:

  • 主题:暗色 / 亮色 / 默认 —— 点击即时切换;
  • 亚克力:模糊已开 / 模糊已关 —— 关掉只去模糊、保留主题;
  • 界面字体 / 代码字体:同一个可搜索下拉,选中即生效,可「恢复默认」;
  • 诊断行:当前偏好 · bg-base 计算值 · chrome on/off · hosts 已挂载/候选 · frost n · panels n。

bg-base 取自 getComputedStyle(document.body),是浏览器实际解析出的值——用来确认主题真的 落到了级联上,而不是「看起来没变化」。

字体探测

浏览器不允许枚举系统已安装字体,因此字体列表由两条路合并而成:

  1. 渲染进程探测(总是可用):候选名字来自 MONO_FONT_BASES × MONO_FONT_SUFFIXES (42 基名 × 6 后缀 = 252 个探测名,后缀含 NF / NFM / Nerd Font / Nerd Font Mono / PL)。 用 canvas 测量候选字体与三个 fallback 下的同一段文本宽度,任一不同即判定存在。
  2. 宿主目录扫描(路由可用时):读取系统字体目录,解析字体文件的 name 表(族名)与 post 表的 isFixedPitch(格式自带的等宽标志),因此能发现候选表之外的族(含 CJK 等宽)。

两者取并集。诊断字段 fontSource 会如实报告 probe / host / host+probe,fontCount 是条目数。

node scripts/check-fonts.mjs          # 打印宿主扫描结果(等宽清单)
node scripts/check-fonts.mjs --all    # 另外打印全部族名

项目结构

dsh-desktop-acrylic/
├── src/
│   ├── theme.mjs          # 调色板、两套皮肤、面板/纹理/字体/桥接 CSS(手写,规范来源)
│   └── client.tpl.js      # 浏览器半边模板(手写)
├── scripts/
│   ├── build.mjs          # 构建 + 自检 → 产出下面两项
│   └── check-fonts.mjs    # 本机字体扫描的调试工具
├── lib/
│   ├── index.js           # 宿主半边:状态路由 + 本机字体路由
│   └── client.js          # 浏览器半边(GENERATED,勿手改)
├── themes/
│   ├── tokyo-night.json
│   └── tokyo-night-day.json
├── docs/desktop-window-material.md
├── cordis.patch.yml       # profile 补丁层:insert 一个 loader 条目
├── package.json           # dsh.bundle.patch + dsh.client.inject 两处声明
└── LICENSE / README.md / .gitignore / .gitattributes / snapdark.png / snaplight.png / setting.png
node scripts/build.mjs     # 或 npm run build

构建脚本在写盘前做四类自检,任一条不通过就直接失败:

  1. 占位符全部被替换,且无残留;
  2. 皮肤数量 / id / 配色方案、默认主题与语言字典一致;字体数据表非空;
  3. token 取值必须符合保守语法(#hex、rgb(a)、color-mix、blur(..) saturate(..)、 transparent、<n>px,或指向自身别名 token 的 var(--dsw-…)),且不含分号花括号;
  4. CSS 安全:模糊必须挂在 ::before 图层上、磨砂面板必须带不透明底色 token,且没有任何规则 给布局容器本体加滤镜或定位。

诊断

插件把运行实况上报给宿主路由,写入 ~/.dsh/dark-acrylic-state.json:

curl http://127.0.0.1:<端口>/dark-acrylic/state       # 状态与上报
curl http://127.0.0.1:<端口>/dark-acrylic/fonts       # 本机字体目录(host 扫描)
curl -X PUT http://127.0.0.1:<端口>/dark-acrylic/preference \
  -H 'content-type: application/json' \
  -d '{"preference": "tokyo-night"}'                  # 主题偏好落盘到 profile 补丁层
curl http://127.0.0.1:<端口>/dark-acrylic/preference   # 回读各 profile 补丁层的 ui-theme 偏好
{
  "version": 2,
  "plugin": "tokyo-night-theme",
  "themes": ["tokyo-night", "tokyo-night-day"],
  "chosen": "tokyo-night",
  "acrylic": true,
  "font": "LXGW WenKai Mono",
  "codeFont": "",
  "preference": "tokyo-night",
  "chrome": true,
  "hosts": 0,
  "hostStats": { "matched": 23, "armed": 0, "skipped": 23 },
  "frost": 1,
  "panels": 1,
  "masks": 1,
  "heals": 0,
  "layer": "written",
  "fontSource": "probe",
  "fontCount": 18,
  "panelDebug": ["div.ZTP_x 900x600 → flat"],
  "maskDebug": ["div.aGz_z → mask"],
  "computed": {
    "bgBase": "rgba(22, 22, 30, 0.1)",
    "sidebar": "rgba(15, 16, 23, 0.1)",
    "menuBlur": "blur(24px) saturate(1.15)"
  },
  "instance": "…",
  "at": "…"
}

hosts / hostStats 用来解释「为什么某处没有磨砂」:matched 是候选容器数,armed 是成功 挂上模糊层的数量——布局列普遍是静态元素,被守卫拒绝是正常结果。heals 是静默重置侦测触发恢复 的次数(健康 shell 中恒为 0,持续大于 0 说明 shell 在反复重置偏好);layer 是偏好落盘状态 (written / unchanged / error / unavailable)。

panels 是当前挂着磨砂面板的对话框数量;panelDebug 逐条说明为什么被挂上或被跳过: div.… 900x600 → flat、→ positioned、→ skip(static, anchored=3)、→ skip(small)。anchored 是 框内 position: fixed/absolute 后代总数——静态对话框本体不是包含块,滤镜一旦落在本体上,这些后代 会被重新锚进框内并被裁剪(工具栏只显示一半),所以含锚定后代的静态对话框一律不做 flat 磨砂。对话框 没效果时,先看这一行。

masks 是背后遮罩被磨砂的数量;maskDebug 记录遮罩命中情况:div.… → mask(命中)或 div.… → no-mask(没找到符合「视口级 fixed/absolute 覆盖层」的父级或相邻兄弟——原生 <dialog> 此时仍走 ::backdrop 规则)。背景没磨砂时先看这一行。

踩过的坑(都写进了构建自检或注释)

  1. 不要给布局容器本体加 backdrop-filter:它会让元素成为 position: fixed 后代的包含块, 而桌面端把侧栏开关、新建会话按钮正是这样钉在标题栏上的——结果就是控件重新锚定、直接消失。
  2. 静态容器里不能放绝对定位的模糊图层:伪元素会逃逸到最近的定位祖先、铺满视口, 把整个界面连同文字一起糊掉(这正是早期「文字不显示」的原因)。因此模糊层只在容器 已经是定位元素时才挂载。
  3. 字体变量不能自引用:--dsw-font-family: X, var(--dsw-font-family) 是 CSS 循环, 会让该变量与所有读取它的 font: 简写一起失效。
  4. 设置槽位只给行组件三样东西:t(来自 locale)、useStore(来自 store)、 以及 inject(actions) 的返回值——props 上没有环境里的主题服务。
  5. 「透」与「磨砂」是两件事:透明来自 alpha,磨砂来自对背后内容的卷积;背后必须存在 可被卷积的纹理,否则调大半径也看不出变化——材质底层就是为此存在的。
  6. 原生控件的样式与滚动不受页面控制:<select> 的弹出列表是系统级窗口,只能靠 color-scheme 间接影响,长列表的滚轮行为也不可靠;需要可控的下拉就得自绘。
  7. 方向性纹理只作用于一列时就是接缝:给侧栏单独加「顶光 + 内高光」会在列的上边缘造出一条 亮线;要连续就用无方向的均匀颗粒。
  8. 明暗感知不对称:同一份颗粒强度,浅色颗粒叠深底很明显,深色颗粒叠浅底几乎看不见, 所以两套主题的同名参数不能共用一个数值。
  9. 对话框不一定是定位元素:模糊若只挂在 ::before 上,静态面板(设置窗口就是这种)会被守卫 整体跳过、表现为「完全没效果」。要覆盖两种结构,就得有一条把模糊直接加在元素上的兜底路径, 并且先排除含 position: fixed 后代的对话框——那类后代正是滤镜会重新锚定的对象。
  10. 运行时主题偏好只在内存里,且 shell 重建后会重放启动时组合的会话快照:切换模型、思考强度、 开关设置窗口等任意设置变更都会重建客户端树,把偏好重置回快照值(经我们界面选的主题从未进过快照, 故为 system)——且不发可靠事件、不重读补丁层(已验证:重置从不写 cordis.patch.yml,运行期写 补丁文件也进不了运行中的会话);快照应用的时机还在我们插件 apply 之后,所以启动时 setTheme 总是先赢后输。对策就是 0.8.6 的恢复网:偏好落盘进补丁层(跨重启有效)、DOM 突变 / 点击事件驱动 heal、theme/change('system') 签名立即重断言 + 事后回读补丁层判定(真选则让位)。

已知边界

Windows 上主窗口没有申请窗口材质(只有欢迎窗口有;macOS 主窗口是 vibrancy: "sidebar")。 因此本插件在 Windows 能做到的是:配色、半透明表面、面板与浮层的磨砂,以及一层应用内的材质 色场;「主界面透出桌面」需要桌面端主进程给主窗口加 backgroundMaterial: "acrylic" 与透明 底色,见 docs/desktop-window-material.md。

prefers-reduced-transparency: reduce 时模糊层自动停用。

变更记录

  • 0.9.22 — 两处都在「我们从来没设过那个 token」这一层,一行一个根因:

    • 卡片的字体:genui 卡片里的每个元素都带 tiny- 类,而卡片库给它们写的是 font-family: var(--tv-font-family);--tv-font-family 又和那 247 个 --tv-color-* 一起声明在卡片的 ID 级调色板块里(Helvetica / Arial / PingFang…)。所以 body 上的字体到卡片边界就断了——继承永远输给一条显式声明。现在字体覆盖同时把 --tv-font-family 写到卡片根节点上([id^="dsh-genui-card-"] + .tiny-card,带 !important,与配色用的是同一套打法)。
    • 设置窗口的磨砂:设置弹层的遮罩是 shell 自己的元素,它的样式是 .mask { backdrop-filter: var(--dsw-mask-blur) },而 shell 把这个 token 的默认值定义成 none(dsh-client-ui-theme 的 body{…} 块,无 !important)。也就是说磨砂从来是「主题要自己填」的开关,填之前所有模态都是不带模糊的。我们以前只设了自家的 --dwa-mask-blur(那条只作用于插件自己画规则的元素),从来没碰过 shell 的这个。现在两份皮肤都写 --dsw-mask-blur: blur(12px) saturate(1.1),一并覆盖设置窗口、快捷键弹窗等所有用标准遮罩的模态——不需要再靠 JS 去给元素打标记。
    • 顺带把这两件事固化成构建期断言:皮肤缺 --dsw-mask-blur 就构建失败;字体覆盖里没有卡片根选择器或 --tv-font-family 也构建失败。
    • 诊断新增 cardFont:把卡片根节点上的 --tv-font-family 与某个子元素实际算出的 font-family 一起回报(形如 LXGW WenKai Mono, … => LXGW WenKai Mono, …)。如果它显示 (unset),说明库自带的 Helvetica 还在生效、覆盖没到卡片——这样「字体变没变」不必靠肉眼判断。
  • 0.9.21 — 补回诊断字段 masks:report() 的负载里少写了 masks: maskCount(早前插入调试字段时的编辑事故),所以快照里只看到 maskDebug、看不到计数。纯诊断修复,不影响渲染。

  • 0.9.20 — 修 fontCount: 0:字体扫描原先只在设置行挂载时才跑(写在 useEffect 里),所以只要没打开过设置窗口,诊断就一直显示 builtin/0——字体其实没问题,只是「量」从未发生。现在在插件激活时主动扫一次并缓存结果(systemFontCache),设置行直接用缓存,诊断首个快照即给出真实数字。实测宿主路由 GET /dark-acrylic/fonts 正常:370 个字体、其中 37 个判为等宽。

  • 0.9.19 — 清掉死代码:SHADOW_HOST_BRIDGE_ENABLED 与 armShadowHosts() 删除(探针已证明卡片是普通光 DOM 元素 shadow=false,该函数从未真正执行)。客户端 bundle 因此少了一段永远不会运行的分支,诊断字段 shadowHosts 一并移除。

  • 0.9.12–0.9.15 — 卡片配色排查(三次尝试 + 一次回滚 + 一支探针):影子宿主回填(被探针证伪:卡片 shadow=false)、元素级类规则(输给库的 ID 选择器)、按需回滚止血、新增 cardRules 诊断。结论:卡片库用 #dsh-genui-card-N 注入调色板,特异性 (1,0,0),任何类规则都赢不了。

  • 0.9.16 — 按探针结论修:桥接同时挂 [id^="dsh-genui-card-"],每条声明加 !important(ID 规则无法压过 !important)。

  • 0.9.17 — 改按「不要背景」处理:卡片容器级 token 全部设为 transparent,并清除卡片根的 background-color / background-image,直接透出页面材质场;文字 / 边框 / 控件 / 代码块 token 保持原值,确保卡片内仍可读。

  • 0.9.18 — review 收尾:① 桥接选择器从全局 [class*="tiny-"] 收窄到卡片子树(否则卡片外的 tooltip / popover / 下拉也会被改成透明);② probeCardSurfaces / probeCardRules 加缓存,避免每次 DOM 变动触发 rearm 时都遍历全部样式表规则。

  • 0.9.11 — 卡片库桥接补全:tiny-vue 一共读取 247 个 --tv-color-* 名称,0.9.10 只补到 60 个,剩下的按钮动作族(act-* 105 个)、边框(border-* 32)、反色文字(text-inverse 25)、空数据(no-data-* 22)、状态图标(icon-* / error/warn/success-icon)仍会退回库默认值——这就是「别的元素还不统一」。现在按族生成整表:249 条桥接覆盖它读到的全部名称,取值一律指向我们的别名 token(品牌色 / 三层表面 / 边框 / 标签 / 状态色),两套皮肤自动同步;token 总数 221 → 410,悬空引用 0。

  • 0.9.10 — 修 QA 卡片(genui / tiny-vue)底色不统一:卡片库把整张调色板声明在 :root 上,并把 --tv-color-* 全部映射到它自己的基础色,我们只桥接了 22 个。于是卡体用的 --tv-color-bg、嵌套面用的 bg-secondary / bg-primary / bg-4 / bg-header 等全部退回库的默认值——亮色是纯白 #fff、暗色是中性灰(截图里 #ffffff 与 #1a1a1a / #262626 正是它们),与我们的蓝调表面完全不同,这就是「QA 框效果不统一」。现在桥接扩到 60 条(bg 面 / 交互 / 文字 / 图标 / 边框 / 状态),并补上卡片库还会要的 --dsw-alias-state-error-tertiary。桥接值仍指向我们自己的别名 token,所以两套皮肤自动同步;token 总数 182 → 221。

  • 0.9.9 — 修设置窗口的磨砂背景:0.2.1 的设置窗口是「portal overlay(role=presentation)+ .mask 兄弟 + 面板(role=dialog aria-modal data-shortcut-modal)」结构。两处改动:① 对话框选择器扩充为 [role="dialog"] / dialog / [aria-modal="true"] / [data-shortcut-modal],角色被改名也不至于失配;② 找遮罩时优先取类名含 mask/backdrop/scrim 的兄弟,而不是父级 overlay——把 backdrop-filter 加在父级会让它成为 fixed 面板的包含块,面板可能被重新定位,而且真正被模糊的是遮罩而不是对话框背后。另:面板一个都没匹配上时,诊断会把候选节点(类名/尺寸/role/aria-modal)写进 panelDebug,下次「磨砂没了」能直接定位。

  • 0.9.8 — 把「背景」找回来:材质强度 30% → 38%(亮色 24% → 30%)、色斑放大、底层渐变掺 10% 主色相;同时把遮住它的大面积表面降回 0.32–0.48(上两版一路抬到 0.49–0.58,几乎把材质场盖没了)。地色保持 root 0.84 / 画布 72%。实测:组合后 8.0–10.4:1,材质最亮处直接压字 4.57:1,叠加表面后最差 5.50:1;亮色一仍其旧。硬下限 0.32,「单独过白底 < 1.6:1 且 alpha < 0.32」判为洞,组合后 < 6:1 同样拦截。

  • 0.9.7 — 再退半档:降级路径目标 2.5:1 → 2.0:1、alpha 下限 0.42 → 0.36;地色也软一档(root 0.90 → 0.84、画布 80% → 72%)。暗色画布 0.56 → 0.49、层 1 0.54 → 0.47、层 2 0.62 → 0.54、层 3 0.67 → 0.58;菜单(0.62)与浮层(0.60)原值仍达标,保持不动;亮色依旧未改。组合后对比度 7.8–10.6:1,仍然稳稳可读。守卫常量同步改为 0.36 / 2.0。

  • 0.9.6 — 退半档:把「每个表面单独过白底 4.5:1」改回两道口径——正常路径靠地色(root 0.90 → 画布 0.80)保证组合后 10:1 左右,降级路径只要求表面「不是一个洞」(2.5:1 或 alpha ≥ 0.42)。暗色画布 0.73 → 0.56、层 1 0.71 → 0.54、层 2 0.81 → 0.62、层 3 0.87 → 0.67,菜单与浮层因为原值已达标保持不变;亮色完全不动。构建守卫同步改成两道判定,且常量独立于 theme.mjs——否则调小旋钮会顺手把守卫关掉(第一版实测就这样放过了 0.10)。

  • 0.9.5 — 可读性下限:表面 alpha 改为按对比度求解。桌面窗口是白的,材质层一旦没画上,浅色文字压在 10% 不透明的暗面上只有 1.3:1 —— 这正是「界面发虚」的来源。现在每个承载文字的表面都会在白底上合成,并要求 --dsw-alias-label-primary 达到 4.5:1(WCAG AA),不达标就提高 alpha:暗色画布 0.10 → 0.73、层 1 0.08 → 0.71、层 2 0.18 → 0.81、层 3 0.24 → 0.87、菜单/浮层 0.60 → 0.74;亮色本就 7.4–8.9:1,保持不变。同时 --dwa-root-base 不再用 transparent(暗色改为 96% 地色),CSS 里的兜底色也从 transparent 换成实色,任何一层都不可能全透明。构建新增守卫:写文件前逐 token 验算,低于 4.5:1 直接 exit 1 并列出违规项(已做反向测试:把上限压到 0.30 时构建如实失败)。 控件也不再是透明洞:字体选择器的收起态与搜索框分别改用 --dsw-specific-input-major 与 --dsw-alias-bg-layer-1;仅保留幽灵按钮的透明填充(它有边框,且位于已知表面上)。

  • 0.9.4 — 适配 DSH 0.2.1-rc.2:dsh-client-* 的 peer 范围改为并集 ^0.2.0-rc.1 || ^0.2.1-rc.2(两条线都接受);从 peer 与 dsh.client.inject 中移除 @deepseek-ai/dsh-client-store——它随运行时打包(客户端仍 require,实测内置客户端代码也在用),但不在共享包清单里,声明成 peer 只会在升级后被误判为「未知包」。运行期行为未变。

  • 0.9.3 — 撤掉卡片正文上的 overflow-x: auto:把它当滚动容器会给绝对定位子元素一个 0 高度视口,「卡片空白」正是这样产生的;改为只保留 min-width: 0,并新增 CARD_CSS_ENABLED 开关,需要时一键关掉整段卡片规则。同时记录「卡片渲染失效」的真实归因:那是 dsh-genui 在 DSH 升级后被拒绝加载(精确版本豁免按 DSH 版本记账,旧授权对新版本无效),与主题无关。

  • 0.9.2 — 适配 DSH 0.2.0-rc.2(5 条 peer 全部复核通过)+ 「全透明」兜底:材质场此前只画在 body::before 上,一旦该伪元素不绘制(层叠上下文变化 / 节点被替换 / 滤镜被丢弃),而 html 底色在暗色下又是 transparent,页面背后就什么都没有,表现为界面整体突然透明。现在同一份材质同时画在 body 自身的 background-image 上,并配近不透明的 --dwa-canvas-base(暗色 88%),最坏情况是画布变朴素,而不是整个界面消失。诊断新增 canvas / material。

  • 0.9.1 — 卡片宽度修复:卡片库用类而不是容器决定宽度(.tiny-card.tiny-card--large-width{width:var(--tv-Card-large-width)},而该变量在 .tiny-card 自身上声明为 4px × 144 = 576px),因此未写 auto-width 的卡片只占半行。现用选择器中和四个宽度类(width: auto; max-width: 100%)。规则放在基础样式里,与亚克力层无关。

  • 0.9.0 — 兼容 DSH 0.2.0-rc.1:peer 依赖升级到 @deepseek-ai/dsh-client-* ^0.2.0-rc.1 与 @deepseek-ai/cordis ^4.0.4;移除已下线的 @deepseek-ai/dsh-client-runtime,客户端模块依赖改为 声明实际提供所需服务的包(store / locale / ui-theme / ui-settings-general)。运行期 API 未变, 无需改动任何插件代码——仅元数据对齐。

  • 0.8.6 — 偏好落盘 + 静默重置侦测:主题选择写入 profile 补丁层的 ui-theme 配置(与原生主题 选择同一落点),跨重启不丢;但 shell 的 ui-theme 配置是会话启动时组合一次的快照,运行期 写补丁文件不会进入运行中的会话——切换模型 / 思考强度、开关设置菜单等任意设置变更触发重建时, 它重放的是会话快照(经我们界面选主题时从未进过快照的 system),把运行时偏好重置回去(已验证: 重置从不写补丁文件)。因此每层重建都需要当场应答:DOM 突变观察者(250ms 去抖 + 廉价预检后直接 heal,无二次去抖)在突变落定瞬间恢复,每次 chrome 同步时重新锚定到当前根元素(防止整树替换后 观察者挂在已分离节点上静默死亡),pointerdown 监听覆盖不改变 DOM 的重置;收到重置签名 theme/change('system') 时立即重断言(否则用户每次改设置都要看 1.5 秒默认主题),随后的 1.5s / 3.5s 两拍经 GET /dark-acrylic/preference 回读补丁层判定:层值仍等于已存选择即为重置, 继续恢复并回写补丁层加固;层值已是 system 即为用户在原生界面真选默认(原生选择会持久化进补丁层, fontSize 同块可证),镜像并让位(重新应用 system)。经我们设置行选「默认」先持久化后发事件, 不会被误反击。诊断新增 heals 计数与 layer 落盘状态(设置行同时显示 heals)。

  • 0.8.5 — 对话框背景遮罩磨砂:弹窗背后压暗页面的遮罩现在挂 backdrop-filter(默认 blur(12px) saturate(1.1),可调 --dwa-mask-blur),透出磨砂主界面;原生 <dialog> 走 ::backdrop;诊断新增 masks / maskDebug,设置行显示 masks。

  • 0.8.4 — 对话框磨砂修复:新增静态对话框兜底路径(模糊直接加在元素上,并先排除含 position: fixed 后代的对话框);诊断新增 panelDebug 与 panels,设置行也显示 panels / fonts。

  • 0.8.3 — 文档:中英文双语 README(README.md / README.en.md)、CITATION.cff 与引用模板。

  • 0.8.x — 字体:改为列出本机可用的等宽字体(渲染进程探测 + 宿主目录扫描,含 NF / PL 变体); 自绘可搜索下拉替代原生 select(原生弹层滚不动);卡片与表格桥接 tiny-vue 调色板; 原生控件 color-scheme 随主题。

  • 0.7.x — 字体输入框 → 下拉菜单(仅等宽);宿主新增 /dark-acrylic/fonts 路由。

  • 0.6.x — 亮色盘整体提亮、降饱和、文字加深;侧栏与画布同源消除竖向色差;颗粒改为无方向均匀纹理 并按主题分设强度;对话框改为真正的磨砂面板(25% 透明 + 30px 模糊)。

  • 0.5.x — 静态磨砂纹理(供无法模糊的侧栏使用)、对话框几何判定试验与相应收紧、 frost / frostTargets 诊断。

  • 0.4.x — 材质底层(柔和色场)解决「没有东西可模糊」;色场强度与预模糊调优; 菜单材质半径与 chrome 层解耦。

  • 0.3.x — 按「用主题的方式实现」重做:两套真实皮肤 + 设置行(主题 / 字体)+ 亚克力层; 分阶段启用定位故障面;安全模式加固(不透明页面基色、可读性优先 alpha、失败隔离、构建期校验)。

  • 0.1.0 - 0.2.x — 早期版本:皮肤注册、设置行、持久开关、透明度档位与相应回归修复。

引用与许可

引用本项目

本项目的正式名称、版本与 URL:

字段值
名称dsh-desktop-acrylic
副题Tokyo Night themes for DeepSeek Harness Desktop
作者LeoLee0097
版本0.8.6
年份2026
仓库https://github.com/LeoLee0097/dsh-desktop-acrylic
许可MIT

BibTeX(推荐,适用于 LaTeX / Zotero / JabRef)

@software{leolee0097_dsh_desktop_acrylic_2026,
  author       = {LeoLee0097},
  title        = {{dsh-desktop-acrylic}: Acrylic {Tokyo} Night style themes for {DeepSeek} {Harness} Desktop},
  year         = {2026},
  version      = {0.8.6},
  license      = {MIT},
  url          = {https://github.com/LeoLee0097/dsh-desktop-acrylic},
  note         = {Dark and light themes, acrylic panels, monospace font picker}
}

GB/T 7714-2015(中文论文常用,电子资源 [EB/OL])

LeoLee0097. dsh-desktop-acrylic: DeepSeek Harness Desktop 的 Tokyo Night 风格磨砂界面主题[EB/OL].
(2026-09-26)[2026-09-26]. https://github.com/LeoLee0097/dsh-desktop-acrylic.

APA 7(计算机软件 [Computer software])

LeoLee0097. (2026). dsh-desktop-acrylic: Acrylic Tokyo Night style themes for DeepSeek Harness Desktop
(Version 0.8.6) [Computer software]. https://github.com/LeoLee0097/dsh-desktop-acrylic

MLA 9

LeoLee0097. "dsh-desktop-acrylic: Acrylic Tokyo Night Style Themes for DeepSeek Harness Desktop." GitHub, 2026,
github.com/LeoLee0097/dsh-desktop-acrylic. Accessed 26 Sept. 2026.

纯文本(README、博客、演示稿末尾一类场合)

dsh-desktop-acrylic — Acrylic Tokyo Night style themes for DeepSeek Harness Desktop, by LeoLee0097 (MIT).
https://github.com/LeoLee0097/dsh-desktop-acrylic

引用日期请替换为你实际访问的日期;版本号随发布更新。机器可读版本见 CITATION.cff。

致谢与上游归属

配色灵感与色值来源为 Tokyo Night(作者 enkia),本项目对亮色盘做了提亮与降饱和处理, 并新增了面板、纹理与桥接层:

enkia. Tokyo Night[EB/OL]. https://github.com/enkia/tokyo-night-vscode-theme.

如果你同时需要使用上游配色,请一并向其致谢;上游与本项目均为 MIT 许可。

License

MIT —— 见 LICENSE。

Comments

Loading…

From the same category

dsh-desktop

by anywhere-labs

为 DeepSeek Harness (DSH) 插件生态打造的现代化桌面端解决方案。万物皆「插件」,桌面本身也是「插件」。

UI & ExperienceManifest valid

★ 31.3k

↓ 115/wk

MIT

TypeScript

Oct 17, 2026

dsh plugin --profile web add dsh-plugin-desktop

by zhu1090093659

DeepSeek Harness (DSH) Web Plugin Aggregation Ecosystem · Everything is a plugin, distributed via the Creative Workshop

UI & ExperienceManifest valid

★ 8.9k

↓ 145/wk

Apache-2.0

TypeScript

Oct 17, 2026

dsh plugin --profile web add dsh-web

A collection of independent Web UI plugins and skins, including task boards, Git graphs, mobile access, and live token stats.

UI & ExperienceManifest valid

★ 8.4k

↓ 145/wk

Apache-2.0

TypeScript

dsh plugin --profile web add dsh-web

by omdsh-dev

开放的侧边栏底座,支持三方拓展注册新侧边栏页面。内置文件渲染编辑/终端/侧边对话/Git/子代理页面 | Open sidebar foundation, supports third-party extensions to register new sidebar pages. Built-in file rendering/editing, terminal, side chat, Git,

UI & ExperienceManifest valid

★ 4.3k

↓ 57.6k/wk

MIT

TypeScript

Oct 17, 2026

dsh plugin --profile web add dsh-better-sidebar

by bowenliang123

The best DeepSeek Harness plugin for context insight and management, with context dashboard / browser / sidebar and context command, for context statistics, composition, breakdown, evolution details,

Tools & CapabilitiesUI & ExperienceTerminal & ClientsManifest valid

★ 2.3k

↓ 52.1k/wk

Apache-2.0

TypeScript

Oct 18, 2026

dsh plugin --profile web add dsh-context

by shaobeichen

把 DeepSeek Harness 装进你的口袋:电脑上跑 dsh web,手机扫码即同步访问(局域网 + 公网,实时同屏)Put DeepSeek Harness in your pocket: run dsh web on your computer and access it synchronously by scanning a QR code on your phone (LAN +

UI & ExperienceManifest valid

★ 1.8k

↓ 3.4k/wk

GPL-2.0

JavaScript

Oct 17, 2026

dsh plugin --profile web add dsh-pocket