dsh-web
zhu1090093659/dsh-webDeepSeek Harness(DSH)Web 插件聚合生态包 · 一切皆插件,创意工坊分发(dsh-market.com)
DSH Web GUI 主题工坊:可切换预设风格、强调色与面板透明度微调、宿主壁纸首帧绘制;wallpaper-engine 玻璃色把浅色主题洗灰时一键改为白色玻璃。
English | 中文
dsh-style-hub 是一个组合插件(宿主半 + 浏览器半),在一张设置卡片里提供三件事:
入口在 设置 → 插件 → 插件配置 → Style Hub。主开关关闭后,外观会完全恢复原样:本插件从不替你的部署决定「正常」长什么样。
设置 → 插件 → 插件配置,当前选中 Dracula 预设:
同一张卡片的壁纸区——上传、填充方式、不透明度、模糊与压暗:
置于设置弹窗中的整体观感:
本包自己接线:dsh.bundle.patch 指向随包的 cordis.patch.yml,它在组合既有的各层之上插入一行宿主条目(dsh-style-hub);浏览器半则由 package.json 里的 dsh.client 清单另行发现。两半都不需要手写条目。
在 DSH Desktop 的 profile 里(最常见的试用方式):
解包进 profile 的 node_modules,目录名与包名一致:
cd "$DSH_HOME/profiles/web/node_modules" # 例如 %APPDATA%/dsh-desktop/harness/profiles/web/node_modules
tar -xzf dsh-style-hub-0.1.0.tgz && mv package dsh-style-hub
在该 profile 的 package.json 里,把 "dsh-style-hub" 加进 dependencies 与 dsh.profile.bundles。
重新安装该 profile(pnpm,hoisted)并重启应用。
在你自己拥有的组合里:把 dsh-style-hub 加进与 @deepseek-ai/dsh-base、@deepseek-ai/dsh-web-app 同一张 bundle 列表,安装后重启。
DSH Desktop 提示:官方插件列表为每个 bundle 维护一个包开关;拨动它(或市场自行协调)会同时改写
dsh.profile.bundles与该 profile 的cordis.patch.yml——增删dsh-style-hub那一行,好让开关与组合结果保持一致。若卡片在该页面的一次操作后消失,请确认两个文件里都还有这条记录,然后重启应用。
要求:一个已经包含 dsh-client-ui-settings-plugins(卡片槽位)、dsh-client-ui-theme(主题注册表)与 dsh-client-locale 的 Web 组合。运行时 peer 范围是 >=0.1.5-rc.2 <0.2.0;npm run build 以 0.1.5-rc.3 做类型检查——那是该系列首个附带类型声明的版本。
宿主会注册 style-hub 设置命名空间、提供 /api/style-hub/wallpapers 路由,并在每次页面渲染时注入开机壁纸规则。webServer 是可选 peer:没有 HTTP 层面的 profile 里该 bundle 照样加载,只是路由与开机规则暂时退场。
打开 设置 → 插件 → 插件配置 → Style Hub。
1 时保留主题自身的填充。卡片是即时写入的,没有保存按钮——因为每个字段都是通过客户端设置作用域的一次带修订号围栏的单字段写入。
setTheme 只持久化 light / dark / system,所以本插件注册的风格无法独自跨越刷新存活;真正重放它的是 style-hub 这一节。也正因如此,用户在本插件介入之前持有的偏好必须被别处记住:浏览器半在启动时捕获它,并持续观察之后的每次 theme/change,因此关掉主开关时是「把偏好还回去」,而不是钉死某个默认值。Stock 则完全不写「外观」——选它就是「让用户自己决定」。
这一节是扁平的(一个字段一次写入),每个值都被校验两遍:宿主 schema 一遍,validateSettings 一遍(区间约束放在后者,这样已存文档可以在 schema 不升级的前提下重新判定)。
| 字段 | 类型 | 取值 / 区间 | 默认值 |
|---|---|---|---|
enabled | boolean | 主开关 | false |
themeId | string | stock 或内置预设 id | stock |
accent | string | #rrggbb,空字符串表示跟随当前风格 | "" |
panelOpacity | number | 0.8 … 1 | 1 |
wallpaperId | string | 十六进制存储 id,或空 | "" |
wallpaperFit | string | cover | contain | cover |
wallpaperOpacity | number | 0 … 1 | 1 |
wallpaperBlur | number | 0 … 50 px | 0 |
wallpaperDim | number | 0 … 1 | 0 |
内置预设 id:nord、dracula、mocha、tokyo-night、gruvbox-dark、solarized-light、github-light、latte。注册时加 sh: 前缀,因此不可能与其它插件的主题撞 id。
$DSH_HOME/dsh-style-hub,可用 DSH_STYLE_HUB_DIR 覆盖):wallpapers/ 存图片字节,index.json 存目录索引。/api/style-hub/wallpapers,按自身子路径分发:GET 目录、POST 上传、GET/DELETE /:id。Origin/Referer;id 是 32 位十六进制,也是路由唯一会读取的路径段;展示名会去掉任何可能被响应头或标记上下文误读的字符。宿主把同一条壁纸规则渲染进 index.html 的注入行,因此第一帧就已经是你的图片;之后该图层由浏览器半接管整个会话。
不做菜单模糊。 给菜单加 backdrop-filter 需要一个设计系统并未提供的稳定钩子——--dsw-mask-blur 虽有声明却无人使用,菜单卡片也没有本插件可以依赖的类名。等价效果改用本插件自己拥有的手段实现:面板半透明(图片之上的表面变半透)与壁纸模糊(图片本身被柔化)。若日后设计系统公布菜单钩子,届时再加模糊选项也不会破坏现有实现。
有壁纸时画布封顶。 ui-layout 用不透明的 --dsw-alias-bg-base 刷满画框,所以在启用壁纸时把该色的 alpha 钉在 0.85——足够让图片读得出来,又不至于让画框不再是画框。
token 是推导出来的,不是抄来的。 每套预设只有十二个色块;tokensFor 由它们推导出整份 --dsw-alias-* 目录,且任何预设都不产出 --dsw-static-*(那是共享常量,覆盖它会把一种风格泄漏给所有其它风格)。测试套件会从已安装的设计系统样式表里读出必需的 token 名单,因此校验对着的是系统本身,而不是一份会过期的副本。
只有一层微调。 强调色与透明度作为同一层覆盖叠放并带指纹,因此一次「什么都没变」的协调不会产生任何写入;空层会被拆除,而不是以「已应用但为空」的姿态留在那里。
首帧就已经是选定的风格。 拥有风格的注册表要等浏览器半注册完才存在,在那之前是设计系统在画原生配色。宿主从同一节推导出同一份 token 目录(含微调),以 script 注入行写到与呈现器完全相同的位置:body 的内联变量、暗色配色属性、根 color-scheme。内联声明压过任何样式表,无论先后;而这些名字正是呈现器自己在跟踪的,因此关掉功能时它们会随呈现器一起被按名撤走,而不会滞留在原生配色之上。
style-hub 一节里;内置「外观」偏好始终是 light/dark/system。刷新后由该节重放。menuBlur。 见上文设计取舍。wallpaper-engine 用自己的持久化「玻璃颜色」(--we-glass-color)给设置弹窗上色,而该值在两种外观下都生效——浅色预设生效时若它仍是深夜蓝,弹窗会读成一片平灰。卡片在冲突发生时会给出「改为白色玻璃」按钮,经该插件自己的设置接口持久化修复(其接口整体替换配置文件,因此走读取-合并-写回);之后若又在它的设置页里改颜色,它会改回自己持有的值,按钮会再次出现。npm install --legacy-peer-deps
npm run check # 类型检查、构建三种产物、语法检查、测试
npm run build 产出:
lib/index.js —— 宿主半,ESM,裸模块标识符保持外部。lib/client.js —— 浏览器半,包在组合模块加载器所期望的 window.__ModuleLoader__.load({ id, factory }) 外壳里。lib/types/** —— 声明树(单独产出,因为源码使用 .ts 扩展名导入)。test/build/*.test.js —— 测试产物(测试直接导入 TypeScript 源码,必须先打包)。测试用的都是 node:test:
npm test
两半如何协作见 docs/architecture.md。
MIT,见 LICENSE。