dsh-shell-themes
v0.1.4
Published
dsh-desktop 内建主题宿主:一个插件承载多个数据主题(themes/<id>/),经 webserver/index-inject 注入活动主题的前端 CSS;主题清单同时供壳复用(窗口底色 / 启动屏)
Maintainers
Readme
dsh-shell-themes
dsh-desktop 内建主题宿主插件(host-only):一个插件承载全部内建数据主题,经官方 webserver/index-inject 通道注入活动主题的前端 CSS;契约 2 起主题还可携带运行时脚本(契约 1 旧壳会整体拒载带脚本主题,避免只注入半套)。
出厂数据主题:原生界面(native,默认,注入空样式)、液态玻璃(aurora-glass,可选,CSS + 可选运行时脚本) 与 深海玻璃(aqua-glass,可选,CSS + 运行时脚本);主题清单同时供桌面壳复用(窗口底色 / 启动屏),随包内容变化自动重新暂存并刷新 profile 安装。
快速开始
本插件随桌面壳内置并自动安装(ensureBuiltinPlugins 标准链),一般无需手动挂载。开发调试:
cd packages/dsh-shell-themes
# 在插件目录内运行,file:$PWD 自动展开为当前绝对路径(必须 file: 而非 link:):
dsh plugin --profile web add file:$PWD安装后重启 dsh web 进程生效;切换主题在托盘「界面主题」中选择。
能力
| 项目 | 说明 |
| --- | --- |
| 多主题单插件 | themes/<id>/(theme.json 清单 + content.css,契约 2 可加 scripts)目录即主题,壳按内容哈希检测变化自动重装 |
| 注入通道 | 监听官方 webserver/index-inject,每次 index 渲染把活动主题 <style> 注入 <head>、把声明的脚本按序作为 {kind:"script", placement:"body"} 行注入 <body> 之后;native 刻意注入零规则 |
| 状态文件 | 三态选择(未选 / 显式关闭 / 指定 id),「关闭主题」不会在下次启动被默认值静默覆盖 |
| 壳复用 | 主题清单同时供桌面壳取窗口底色与启动屏配色,单一来源 |
| 自愈 | profile 被重装/清空后,壳下次启动自动重新暂存并安装 |
aurora-glass(液态玻璃)
契约 2 主题:极光流动背景 + 磨砂玻璃面板(Apple Liquid Glass 取向),content.css 先重映射 --dsw-alias-* 等设计令牌、再对关键表面做玻璃化(文件头部有 v1–v36 的实测演进记录)。
ambient/ 下 2 个自包含脚本提供可选运行时:
| 脚本 | 内容 |
| --- | --- |
| aurora-core.js | 命名空间 window.__DSH_AURORA、设置存储(dsh.ui-aurora.*)、明暗同步、模块注册表、右下角齿轮调参面板 |
| aurora-spotlight.js | 光标跟随的极光光晕(固定 640×640 径向光斑,移动与缩放全走 transform,纯合成不重绘) |
默认开启(enabled=true):注入即生效,无需任何操作。右下角一枚 28px 齿轮可随时关闭与调参(总开关 / 光晕半径 / 色相 / 强度 / 恢复默认);关掉后不创建任何 DOM、不注册任何事件,零视觉/性能开销。唯一例外:系统开启 prefers-reduced-motion 时默认不启用(仍可手动打开并持久化)。DSH_SHELL_THEME_SCRIPTS=0 可退回纯 CSS,外观不受影响。
皮肤覆盖:三栏 / 头部 / 输入卡 / 气泡 / 浮层 + 审批视图(ag-*)、对话流代码块与内联码、轨迹视图内部面(时间线画布 / 表格 / 搜索框)。新加的规则一律使用前端自带的稳定锚点(md-code-block、data-code-block-banner、[data-chat-flow]、data-trajectory-scroll),不再依赖会随构建腐烂的哈希类。
取向:本主题不含深海元素(流体 / 鲸鱼 / 海洋生物 / 环境生物)—— 那是深海玻璃(aqua-glass)的语言;极光与液态玻璃是本主题的身份。
aqua-glass(深海玻璃)
契约 2 的脚本主题,是上游 DSH-Transparent-UI-Plugin(MIT,npm dsh-client-ui-aqua)Aqua 主题的一比一移植:content.css = 上游 aqua.module.css + fonts.module.css(Space Grotesk Variable 自托管 woff2)+ theme-layer.ts 的 83 条 --dsw-* token 覆盖(float/compat × 明暗四块);动态层拆成 ambient/ 下 7 个自包含脚本,对应上游模块:
| 脚本 | 上游来源 | 内容 |
| --- | --- | --- |
| aqua-core.js | theme-layer.ts / critters.ts / seam-stamper.ts / wallpaper-store.ts | 设置存储、明暗同步、CSS 变量与 data-dsh-* 属性、接缝盖章器、环境场景与页面渐变带、壁纸层、IndexedDB 媒体库、模块编排、调参面板 |
| aqua-fluid.js | fluid-shader.ts / fluid-interactions.ts / fluid-tones.ts | WebGL2 流体背景(deepseek.com 同款着色器) |
| aqua-whale.js | whale.ts | 粒子鲸鱼 |
| aqua-mesh.js | mesh.ts | 指针排斥点阵网格 |
| aqua-spotlight.js | spotlight.ts / spot-core.ts | 光标聚光 + 悬停 3D 倾斜 + 按压 |
| aqua-greetings.js | greetings.ts | hero 问候语与输入框占位文案 |
| aqua-wordmark.js | wordmark-badge.ts | 深色模式的侧栏 "Harness" 品牌徽章 |
样式与脚本共用上游的稳定命名:根门控 <html data-dsh-aqua>,模式属性 data-dsh-float(毛玻璃)/ data-dsh-compat(兼容),样式键控点 data-dsh-frame / -sidebar-root / -surface / -inputbar / -trajectory / -details / -add / -stats / -wordmark(由核心的接缝盖章器在运行时盖上),CSS 变量 --dsh-aqua-*,设置键 dsh.ui-aqua.*(与上游插件互通,两实现间切换不丢设置),媒体库 dsh-aqua-media。因此样式表不含任何构建哈希类,前端升级不会让它失效。
脚本是自包含经典脚本(无 import)、幂等挂载、不向页面抛异常、隐藏页暂停动画、prefers-reduced-motion 只画静态帧;脚本缺失或被 DSH_SHELL_THEME_SCRIPTS=0 剥掉时,content.css 靠 html 级 var(--dsh-aqua-*, …) 回退值保持默认玻璃外观。右下角齿轮浮层的控件与上游 AquaAppearanceRow 对齐(模式 / 模糊 / 磨砂 / 流体色相与深度 / 背景亮度 / 背景源 / 壁纸图与视频 / 动物、网格、聚光、按压开关 / 壁纸与视频模糊亮度 / 总开关 / 恢复默认)。
未移植的两处上游能力:fsa:(File System Access 视频句柄,本主题统一走 IndexedDB blob);上游的 React 设置页插槽(settings.plugin.item 等)在本主题通道不可用,改为自带浮层面板。上游皮肤之外自补的两处:① 审批视图(「自动放行审批」记录页)——上游目标版本没有该视图,面板原本保持 token 的纯白底、与玻璃语言割裂,现按同一套玻璃语言补了 17 条规则(锚点用审批 UI 的语义化稳定类名 ag-*,如 .ag-view 玻璃卡片、.ag-view-head 发丝分隔、.ag-row:hover 玻璃浮起、.ag-set-btn / .ag-tag / .ag-file-chip 玻璃化 + 全套 dark 变体);② 对话流的 Markdown 代码块与内联代码(上游同样未覆盖该形态,token 给的是实心浅底 rgb(240,245,251) / 内联 rgb(228,237,248),在流体背景上割裂)——按同一语言改成半透明玻璃面 + 细描边,锚点用 .md-code-block(语义化类)、[data-code-block-banner](稳定属性)、div:has(> banner)(命中哈希化的顶栏 wrapper)与 :not(pre) > code(区分内联/块内代码)。两处都只改视觉属性(发丝线用 box-shadow 而非 border),保证零布局影响;内联代码上千个一律不加 backdrop-filter,代码块属内容区也一并不加模糊,守住「blur 收敛在小块」的取向。另有两处宿主兼容改动,均因本机 dsh(0.1.5-rc)DOM 与上游目标版本不同:① aqua-wordmark.js——上游用 btn.querySelector('svg') 取字标,而本机 brand 按钮里鲸鱼图标在前,故改为优先选中含徽章板的那支 svg(选不到才回落上游行为);② aqua-spotlight.js——上游 localTopLeft 沿 offsetParent 链取坐标,offsetParent 只经过已定位祖先,本机部分面板([data-dsh-inputbar]、按钮式 [data-dsh-surface])不在链上,导致返回文档坐标(超长会话下数万 px),写进 position:absolute 光斑的 inline top/left 会把文档滚动区撑开(表现为「聊天内容后一大片空白 + 整页滚动条」);现已加视口 rect 差值兜底 + inline 盒范围校验(异常时退回 CSS inset: 0),并配回归断言。
配置
| 环境变量 | 默认 | 说明 |
| --- | --- | --- |
| DSH_SHELL_THEME | (未设) | 指定主题 id(如 aqua-glass);0/off/false 强制无主题;未知名回退默认并告警 |
| DSH_GLASS_THEME | (未设) | 旧名兼容别名,语义同上 |
| DSH_SHELL_THEME_STATE | <DSH_HOME>/... | 主题选择状态文件路径(托盘切换写入) |
| DSH_SHELL_THEME_SCRIPTS | (未设) | 0/off/false 时剥掉主题运行时脚本行,CSS 照常注入(保留纯 CSS 外观) |
原理一句话
启动时扫描 themes/ 目录读入各 theme.json 清单(损坏目录只告警不拖垮插件树),按 环境变量 > 状态文件 > manifest 默认 的优先级解析活动主题 id,并在每次 index 渲染时把该主题 CSS 经 webserver/index-inject 注入、把声明的脚本按序注入 <body> 之后——只改主题,不碰插件与前端。实现见 src/index.mjs 与 src/themes.mjs。
文档
| 文档 | 内容 | | --- | --- | | ../../docs/THEMES.md | 完整文档:切换方式、新增主题、CSS 写法约定、类名轮检流程、注入顺序取舍、排障 | | ../../docs/CHANGELOG.md | v12–v31 修复史(实测驱动) |
测试
node test/shell-themes.test.js # 清单/契约/出厂主题/脚本注入(10 条)
node test/theme-runtime.test.js # 主题运行时 + scripts 校验(19 条)
node test/theme-surfaces.test.js # 壳侧窗口底色/启动屏复用(12 条)
node test/shell-themes-classes.test.js # 类名轮检:哈希类基线守卫(2 条)
node test/legacy-frontend-theme.test.js # legacy 前端补丁清理(14 条)版本与兼容
包名 dsh-shell-themes(原内置插件 dsh-liquid-glass-theme 已重命名并入)· MIT · 目标 DSH 0.1.5-rc.2(实测基准)。
npm 版本线与主题内容版本相互独立:包版本只在发布时按 ../../docs/VERSIONING.md 进位,内部修复史以 aurora-glass 的内容版本(themes/aurora-glass/content.css 头部 vN)记录,不占 npm 版本线。
- 0.1.4(0.1.5-rc.2 适配:产物 chip 选择器静默失效修复,补丁位 +1):两个玻璃主题都用
[class*='producedChip']给对话流的「生成的 N 个文件」产物 chip 上玻璃面,该子串在本机 0.1.5-rc.2 前端里零命中——组件已改名为dsh-client-ui-deliverables的ProducedFiles模块(P4kPIW_root/_label/_lane/_row/_file/_more),旧规则静默失效(深色模式下残留一块实心白)。现改用该组件唯一的稳定锚点data-produced-files-row(其 row 容器自带),不引入哈希类,符合本文件「稳定锚点优先」的既有取向;仅视觉属性,零布局影响。附带核查:本主题引用的 45 个哈希类全部命中、基线 fixture 0/46 过期、aqua 的 33 个data-*经溯源全部由主题自身脚本创建(非腐烂),另有两处零命中选择器判定为无害(data-dsh-panel-host是第三方dsh-better-sidebar的运行时接缝;[data-radix-popper-content]所在逗号列表的活兄弟选择器已覆盖同一批声明)。测试:主题五套件 62/62、全量套件 394/394。 - 0.1.3(0.1.2 发布 tarball 主题实现缺失,以仓库当前内容重发,补丁位 +1):0.1.2 的 npm tarball 由未合入最终主题实现的工作区快照构建——README/清单已描述的 v32–v35 修复、aqua-glass 移植与宿主兼容修复,tarball 里的
themes/代码实际是旧草稿(12 个文件、约 840 行缺失,如 aqua-spotlight 缺 PORT-CONTRACT 合并与「视口 rect 差值兜底 + inline 盒范围校验」、aqua-wordmark 缺 svg 优先选取)。0.1.3 以仓库当前已提交内容重新发布,补齐全部主题实现;无新 API / 行为变更,用户升级无需改变使用方式。测试:主题四套件 44/44 +test/manifest.test.js12/12。 - 0.1.2(主题契约 2 + 主题修复轮 v32–v35,补丁位 +1):清单契约升至
2并新增scripts字段,宿主支持按序注入主题自带运行时脚本({kind:"script", placement:"body"}行);新增脚本主题 aqua-glass(深海玻璃)——上游 Aqua 主题的一比一移植,content.css(上游皮肤 + 3 段 Space Grotesk@font-face+ 83 条--dsw-*token 覆盖)+ambient/七个脚本(核心 / 流体 / 鲸鱼 / 网格 / 聚光 / 问候 / 徽章),样式键控上游data-dsh-*接缝与--dsh-aqua-*变量、设置键dsh.ui-aqua.*;DSH_SHELL_THEME_SCRIPTS=0剥脚本保 CSS;脚本路径逃逸在清单校验即硬错,缺失只软告警跳过;旧壳(契约 1)整拒契约 2 主题防半套。测试:主题四套件 10/19/12/2(43/43),新增脚本注入顺序 / 转义 / kill-switch / 七个模块清单 / 上游样式标记覆盖。- v32–v35 修复轮(观感一致 + 根因修复):v32 轨迹 / 审批页隐藏消息输入框(前端缺陷防御)、v33 composer 卡片对齐原生界面、v34 设置面板不再被输入框压住(侧栏层叠修正)、v35 注释里的通配符序列提前闭合注释导致
.hHd-Xa_iconButton过渡被整条丢弃; - 输入框隐藏规则改用前端稳定锚点(触发
[data-conversation-composer-overlay]/[data-trajectory-scroll]/.ag-view× 目标[class*='composerSeat']与:has(> [data-composer-card])),两个玻璃主题取齐;设置页打开期间另有兜底隐藏; - 侧栏不再创建层叠上下文(删除入场动画与
z-index):设置页的固定遮罩重新参与层叠,右栏 / 输入框不再盖住设置页; - 右栏面板与栏内界面按主题语言皮肤化(面板玻璃渐变、顶部控件 / 文件树行 / 空态文字),锚点全用前端稳定属性、零哈希类;
- 极光运行时改为默认开启(面板可关;系统开启「减弱动效」时默认不启用);
- 新增宿主行为防御层
base.css(与主题无关、先于活动主题注入,native 同样生效):轨迹 / 审批页与设置页打开期间隐藏消息输入框;零配色 / 圆角 / 阴影,files已含该文件; - 测试:主题四套件 44/44 全绿(
shell-themes11 /shell-themes-classes2 /theme-surfaces12 /theme-runtime19)。
- v32–v35 修复轮(观感一致 + 根因修复):v32 轨迹 / 审批页隐藏消息输入框(前端缺陷防御)、v33 composer 卡片对齐原生界面、v34 设置面板不再被输入框压住(侧栏层叠修正)、v35 注释里的通配符序列提前闭合注释导致
- 0.1.1(补丁位 +1,主题修复轮 v17–v31):修复与观感统一,无破坏性变更——已选主题的用户观感更一致,无需改变使用方式。
- v17 切换/滚动卡顿根治:去掉两层全屏背景层的无限呼吸动画、常驻宽表面(顶部会话条 / 任务坞)去掉
backdrop-filter、入场动效整体减半; - v25–v27 三页(对话 / 轨迹 / 审批)底色统一:实测定位「多层半透明白叠加」为色差真凶(对话 1 层 / 审批 2 层 / 轨迹 4 层),改为只保留唯一基准层
centerCol,视图自身白层全部归零; - v28–v29 顶部会话条与标签栏并入基准色(
.wSkVaW_root/.wSkVaW_header归零,与内容区无缝); - v30–v31 轨迹页顶部时间线概览区并入基准色(画布
_1p9O6q_plot透明化、搜索框玻璃化、工具条按钮 hover/激活态玻璃化); - 类名轮检基线随前端哈希扩充(新增
qBU-ya_root/wSkVaW_root/_1p9O6q_plot/fV0t5q_*等),主题四套件 40/40 全绿。
- v17 切换/滚动卡顿根治:去掉两层全屏背景层的无限呼吸动画、常驻宽表面(顶部会话条 / 任务坞)去掉
- 0.1.0(npm 首发):v16——右栏把手选择器改同特异性覆盖(
[data-dsh-part="resize-handle"]在安装版前端不存在)、清理 5 个腐烂哈希类、legacy 清理补 PATH 缺口/多链接/g/首行归属、未知主题 id 告警、类名轮检测试落地;一并随首发包含 v12–v15(对比度、三栏/气泡/把手对齐新版前端、树不误涂、轨迹表与审批空态玻璃化);出厂默认主题为native(液态玻璃转为可选)。
元信息与文档结构遵循 docs/PACKAGE-TEMPLATE.md。
