HwFee/HwFee-dsh

system-fonts

内容、代码与终端文字各一个字体槽,另加界面字体、界面字号步进器与行内代码字号步进器,附行距与字距。只改排印,不动配色。

UI 強化deepseek-harnessdshdsh-market

dsh-system-fonts

DeepSeek Harness (DSH) 的系统字体与行距插件。

它干三件事:把宿主原本要手敲名字的三个字体输入框(正文 / 代码 / 终端)换成能直接选本机字体的下拉菜单;补上界面字体与界面字号 / 行内代码字号两个像素步进器;再顺手补上行距和字距两个滑块。

它不改配色,也绝不写任何 `font-weight`。字号只碰两处:界面文字(逐文本节点放大,不改布局)与行内代码(写宿主自己的代码字号轴)。正文与终端字号仍由宿主管理。

安装与卸载

在命令行运行,或在 DSH 的 设置 → 插件 → 添加插件 里直接输入 dsh-system-fonts:

dsh plugin --profile desktop add dsh-system-fonts

装完或卸完后必须彻底退出并重开 DSH。

卸载:

dsh plugin --profile desktop remove dsh-system-fonts

在哪里调

重开 DSH 后,打开 设置 → 通用设置,点击「字号大小」右侧的展开箭头(「更多字体设置」)。

插件的控件直接长在宿主原生的可折叠字体区里面,各自跟在它替换掉的官方行位置上:

  1. 正文字体:下拉选择本机字体(作用于界面、侧栏、按钮与对话正文)
  2. 代码字体:下拉选择本机字体(作用于行内代码与代码块)
  3. 行内代码:像素步进器(10–20px;未设置时显示 12px),紧跟「代码字体」、取代宿主的「代码字号」行。只改行内代码字号——代码块、工具输出与终端按主题固定,这是宿主 --dsh-code-font-size 派生链本身的行为
  4. 终端字体:下拉选择本机字体(作用于集成终端,字号仍用宿主的「终端字号」步进器)
  5. 界面字体:下拉选择本机字体(只作用于界面控件;默认跟随正文)
  6. 界面字号:像素步进器(10–20px,默认 14px),只放大界面文字,不改布局
  7. 行距(Line height):滑块 50%–100%,按比例收紧 Markdown 各级字阶的行高,拖动实时生效
  8. 字距(Letter spacing):滑块 −0.30em ~ +0.30em(0 为默认),微调 Markdown 正文的字符间距

把「字号大小」折叠收起时,这些行也会跟着一起收起,不会在外面留尾巴。下拉框支持搜索过滤,底部可以一键「恢复默认」或「重新读取系统字体」。

为什么这么设计

1. 只管字族,不碰字重(Weights belong to the theme)

DSH 的排印系统有 30 级字阶,每档的 font 简写里自带字重,而且宿主原生 CSS 里有 357 处 font-weight 声明,基本不靠继承。如果字体插件强行写一个全局字重,会把主题(比如 dsh-cds-theme 里的 8 档可变字重和暗色减薄)好不容易对齐的层次全冲乱。所以早先版本的字重选择器已经砍掉,本插件只管换字族和调间距。

2. 与宿主共享同一个状态源

选好字体后,插件直接调用宿主 theme 服务的 theme.setFontFamily(role, value)。格式化、持久化和 theme/change 广播全走宿主自己的通道。

这里专门防了一个坑:宿主里的三个字族字段是 volatile() 的,每次刚重启时快照报告的都是空字符串 ""。如果无脑把宿主的空值同步回本地,重启一次你选好的三个字体就全没了。现在的逻辑是:宿主有非空值时听宿主的;宿主报空串但本地 localStorage 里存过你的选择时,主动把你的选择重新写回宿主管线。

3. Windows 字体清单怎么来的

浏览器标准的 queryLocalFonts 在 DSH 里用不了(宿主没开权限)。本插件在 Host 端合并了三路数据:

  1. PowerShell + `InstalledFontCollection`:拿到 GDI 规范族名(保证写进 CSS 能被解析)。
  2. 注册表 `Fonts` 键(HKLM + HKCU):提取本地化显示名。
  3. 逐文件 `GlyphTypeface` 元数据:读取字体文件里的 Win32FamilyNames,把 PingFang SC 和 苹方-简 这类同族中英文别名归并到一起。

首次枚举约 3 秒,之后常驻进程内缓存;非 Windows 环境或读取失败时,下拉框会自动退化成手填字体名的输入框,不会报错卡死。

本地开发与测试

npm ci                # 仅安装打包工具 esbuild,零运行时依赖
npm run build         # 编译客户端产物:client/src/* -> client/client.js
npm test              # 产物新鲜度检查 + 清单契约 + 全部单测(含真实 @deepseek-ai/cordis 激活测试;条数以输出为准)
npm run verify        # 端到端验证真实字体枚举与样式表生成
npm run integration   # 跑完整集成校验