dsh-type-tune
Verifieddsh-type-tune · v0.1.0 · Apache-2.0 · Web UI
DSH Web GUI typography & readability tuner: wallpaper-aware contrast repair, edge recolor and hue-cycle effects, per-content rules (bold+underlined links, tinted headings) and a floating WYSIWYG preview window.
Install
dsh plugin add dsh-type-tune Confirm the layer applied with dsh --profile default --dump-config — see the install guide.
Source
Tags
Creators
Readme
dsh-type-tune
DSH Web GUI 排版与可读性调校插件:专治「改了壁纸之后原版字体发虚 / 发淡」这一类问题,并提供轻量的字体特效与内容规则。
- 可读性修复(核心):覆盖
--dsw-alias-label-secondary/tertiary/caption三个低对比 token(用color-mix向label-primary靠拢,亮/暗主题自适应),再叠一个可调强度的文字光晕,把叠在壁纸上的次级文字(轨迹、重试提示、工具摘要)拉回可读。 - 内容规则:链接加粗 / 常驻下划线 / 变色,标题变色,正文变色——作用范围精确锁定在会话 Markdown(
[class*="_markdown_"]),不碰侧栏和设置页。 - 特效:彩虹描边(
@property --dtt-hue做色相循环)与渐变填充(background-clip: text平移),速度 / 方向 / 渐变角度 / 描边宽度 / 色标全部可调;默认只作用于标题、强调、链接。 - 预览小窗:可拖动的悬浮 WYSIWYG 预览,正文区透明、壁纸直接透出,附带 WCAG 对比度徽标。
- 两档 UI:简单模式只有预设卡片 + 对比 + 光晕 + 链接/特效开关;高级模式展开渐变角度、描边宽度、色标等细节。
安装
从 GitHub 安装(推荐;零构建,无需编译):
dsh plugin --profile <你的 profile> add github:AWL-MC2/DSH-Plugin_awl
或以本地目录安装(开发 / 自用):
dsh plugin --profile <你的 profile> add <插件目录绝对路径>
安装后重启一次 DSH 并刷新 Web UI(改设置之后无需再重启)。
使用
打开 设置 → 通用 → 「字体与可读性」。改完即时生效。
- 字号基准仍由 设置 → 外观 → 对话字号 控制;本插件的「正文字号偏移」在其上做增量,不与之冲突。
- 预览窗可用右上角 ✕ 临时隐藏;在设置里取消再勾选「显示预览窗」可重新打开。
自定义字体
把字体文件丢进插件目录下的 fonts/(首次启动会自动创建,里面带一份 README.txt),
刷新页面就能在字体下拉框的「自定义」分组里选到它们。
dsh-type-tune/fonts/ ← 主目录,跟着插件走
$DSH_HOME/fonts/ ← 备用目录,重装插件也不会丢
| 项目 | 说明 |
|---|---|
| 支持格式 | .ttf .otf .woff .woff2 |
| 不支持 | .ttc / .otc(字体集合,浏览器无法通过 @font-face 加载;Windows 自带字体常是这种,会被明确列在"跳过"里而不是静默消失) |
| 家族名 | .ttf/.otf 读字体自带的 name 表(优先排版家族名 nameID 16);.woff/.woff2 用文件名 |
| 同名家族 | 只保留一个:文件名与家族名一致的那个优先,落选者在设置卡里报告 |
| 生效方式 | 点设置卡里的「重新扫描」,或刷新页面(无需重启 DSH) |
/style 聊天命令
在对话框输入即可,改动约 1 秒内出现在页面上(页面每 2 秒轮询一次状态;后台标签页不轮询)。
| 命令 | 作用 |
|---|---|
/style 或 /style status |
查看当前状态 + 自定义字体数量 |
/style help |
列出全部命令 |
/style recover |
恢复默认(清空所有覆盖),别名 reset / default |
/style fonts |
列出发现的自定义字体、扫描目录,以及被跳过的文件与原因 |
/style preset <off|nebula|reading|neon|softgrad> |
应用预设 |
/style contrast <0-3> / /style halo <0-3> |
对比增强 / 文字光晕 |
/style fx <off|rainbow-edge|gradient-fill> |
特效类型 |
/style links <bold|underline|both|off> |
链接加粗 / 下划线 |
/style font <家族名|auto> / /style code <家族名|auto> |
界面字体 / 代码字体 |
/style size <-2..4> / /style preview <on|off> |
字号偏移 / 预览小窗 |
数据与安全
- 设置存在
$DSH_HOME/type-tune.json,是聊天命令与设置卡唯一的共享真相源;浏览器另存一份localStorage仅作首帧缓存。宿主的webserver不可用时(桌面端 / Electron)自动退回纯localStorage模式。 - 状态文件里有一个
present标志:区分「还没有状态文件」与「用户主动恢复了默认」。升级不会覆盖你已有的设置——首次联通时反而会把你现有的配置播种给宿主,这样后续/style的改动是在你的真实配置上叠加,而不是叠在默认值上。 - 宿主半开的
prefix路由是只读优先的:GET供页面读取字体与状态;唯一的写入口POST /state额外要求Content-Type: application/json且Origin与Host同源,跨站表单/请求拿不到这个组合(不授予任何 CORS 预检)。字体 id 也做了白名单校验,路径穿越无效。 - 该路由不带认证:默认只在回环地址可用;如果你把 DSH 绑到
0.0.0.0,字体与状态对那个网络可读(写入仍受同源保护)。
已知取舍(重要)
- 彩色循环 / 描边会牺牲 Windows ClearType 次像素锐度,且天然与高对比冲突;插件默认只在标题/强调/链接等少量节点上启用。
- 「正文特效」会显著增加渲染开销,长文本请慎用(UI 有警告)。
- 字体文件通过
@font-face按需加载(font-display: swap),首次选择某个自定义字体时会有一次极短的切换。
回滚
dsh plugin --profile 0.1.7-rc.2 remove dsh-type-tune
或只清掉状态与本地偏好:
del %USERPROFILE%\.dsh\type-tune.json
浏览器控制台:localStorage.removeItem('dsh-type-tune:v1') 后刷新。
开发
- 零构建:
index.js(宿主半)+client.js(window.__ModuleLoader__.load包裹的浏览器半)。 - 语法检查:
node --check index.js && node --check client.js。 - 三套离线测试(全部无依赖、无需 DSH 进程)。
说明:测试文件位于作者开发工作区的
dev/目录,不随本仓库发布;下表记录的是本插件实际被验证过的范围。
| 命令 | 覆盖 |
|---|---|
node dev/test-host.mjs |
用真实系统字体验证 name 表解析(Georgia / Consolas / Noto Sans SC)、.ttc 与损坏文件拒绝、目录扫描与同名家族仲裁、状态读写、全部 /style 子命令、路由(含 CSRF 与路径穿越拒绝)、字体字节、无 webserver 宿主的降级 |
node dev/test.mjs |
浏览器半:vm 加载、种子词约束(守住曾导致 boot 失败的那条 require)、配置归一化与 CSS 注入、字体值反注入、降级路径 |
node dev/test-integration.mjs |
端到端:把浏览器半的 fetch 直接桥接到真实路由处理器,验证「升级不丢设置并把配置播种给宿主 → manifest 变成 @font-face → 字体路由返回正确字节 → 卡片写入落到状态文件 → /style 回流到页面 → /style recover 清空覆盖」 |
硬约束:只允许 require 平台种子词
浏览器半的 require() 只能命中平台种子表,否则整个 boot entry 会以
client-modules: require("…") missed the module table 失败(本插件 v0.1.0 首次发布就踩了这条,
当时误用了旧宿主线的 @deepseek-ai/dsh-client-runtime/client)。
DSH 0.1.7-rc.2 的种子表就这几个:
react · react/jsx-runtime · react-dom · react-dom/client ·
@deepseek-ai/cordis · @deepseek-ai/dsh-client-store ·
@deepseek-ai/dsh-client-ui-slots · @deepseek-ai/dsh-client-ui-primitives ·
@deepseek-ai/dsh-client-ui-dockkit
因此本插件刻意 只 require react 与 react/jsx-runtime:
设置行的响应式状态用自建的订阅集合 + React hooks 实现,不依赖 store 引擎;
slots / locale 只作为 服务(ctx.inject)获取,不走 require。
dev/test.mjs 会在 vm 里复刻真实报错来守住这条约束。
另:插件导出 inject = [](空服务前置条件),设置卡通过 ctx.inject(["slots","locale"], …)
按需挂载——这样即使宿主缺某个 UI 服务,也只会降级为"无设置卡",而不是失败整个入口。
License
Apache License 2.0 © 2026 AWL-MC2