跳到正文
dsh-market 浏览插件 GitHub EN

LyaxZ/dsh-fonttune

DeepSeek Harness 字体插件:对话拥有字体、字号、行高与字重,界面用字体与字重并默认跟随对话(也可独立设置,两边互不影响),代码独立成轴并支持连字,整套配置可存为预设方案。

Star 数 ★ 4 分类 UI 增强 收录于 2026-09-18 npm dsh-fonttune

安装

在 DeepSeek Harness 里通过 dsh-market 安装

dsh plugin --profile web add dshmarket

或使用命令行

dsh plugin --profile web add dsh-fonttune

装任何插件都等于在你的机器上跑第三方代码,权限和你本人一样大——能读你的文件、用你的凭据、访问网络。请先审阅源码,并尽量锁定 commit(github:owner/repo#sha)。

README

English | 中文

DeepSeek Harness(DSH)字体插件:对话(会话 Markdown 正文)拥有完整的排印控制——字体族、字号、行高、字重;界面(设置页、侧栏、工作区、按钮)提供字体与字重并默认跟随对话;代码独立成轴,另有连字与特性开关;整套配置可存为预设方案。配置入口是 设置 → 插件 → 插件配置 里的原生卡片(分区收起 + 摘要),改完即时生效。

功能

  • 三套排印:对话(会话 Markdown 正文、表格与标题)排在第一位、拥有全部轴;界面(设置页、侧栏、工作区与标题按钮)提供字体与字重、默认跟随对话(可关);代码独立成轴
  • 界面 / 对话 / 代码字体 —— 各自独立的字体回退列表,拉丁字体在前、中文字体在后;留空表示完全沿用 DSH 的字体栈
  • 字号偏移 —— 对话字号 -3 ~ +6 px,加在 DSH 自己的「对话字号」之上(官方数值是基准),段落、标题与行高一起跟随,且只在源头加一次(H1/H2/H3 的尺寸都由同一条 delta 派生,任意偏移下层级都不变、也不会出现某个标题偏小);代码字号独立成轴,-3 ~ +6 px。界面没有字号轴:经实测 DSH 的设置页、侧栏与工作区把字号写死在上游 CSS 里,唯一官方字号接口就是「对话字号」
  • 字重偏移 —— 对话、界面与代码都是同一种相对偏移(未设置即 0、读数按 +n / -n 显示,范围按当前字体实测):偏移叠加在每个元素自身的字重上,标题仍按 DSH 的层级(h1h3 700、h4h6 与加粗 600、表头 500、正文 400)逐级保持"标题明显粗于正文",调重调轻都不会把层级抹平,代码块里的粗体也不会被压平。界面偏移是一条把对话 Markdown 整棵子树排除在外、只铺 body 与自带字重的元素表的规则:真机实测(活页面计算样式)它把界面的文本元素改到目标值、对话 markdown 里的元素一个都没动,所以改界面字重不会碰到对话。滑块按档计数:读数就是档数(例如 -1 0 +1),档数由字体决定——卡片会在页面里量出所选字体在正文处实际能渲染出几种粗细,一档取变化足够明显的那一档(不是最细的那一档),范围到正文再也换不到字形为止(加粗与标题到顶后停住),所以档数可能比之前少,但每挪一格都看得出来,数字也不会出现"几百几百";换字体会重新测量。文档里存的仍是字重偏移(旧值自动换算),换字体不会把设置改坏;字体只有常规与粗体两档时就只有 2 个档位,要连续可选用字重档位多的字体或可变字体
  • 行高 —— 对话行高用倍率(100% ~ 160%);代码行高用加法偏移(-4 ~ +8 px)。界面没有行高轴(同字号的原因)
  • 代码连字 —— 三档开关(默认 / 开启 / 关闭,浏览器默认即开启,关闭可还原 =>、!= 这类连字),高级模式另有 font-feature-settings 特性值输入
  • 拒绝合成样式(默认关闭 = 允许合成) —— 打开后禁用浏览器为中文伪造的斜体与粗体(中文字体没有斜体字形,浏览器会硬掰);关着(默认)时由浏览器按自己的规则合成,字体缺粗体字形时至少还能看出"粗体"这一档
  • 界面跟随对话开关 —— 界面分区顶部的「跟随对话设置」开关(默认开启):开启时界面沿用对话的字体与字重,界面自己的两个控件隐藏;关闭后界面用自己的字体与字重,与对话互不影响。字号与行高只属于对话(界面没有这两个接口)
  • 预设方案 —— 编辑模式正下方的下拉选择框:五个默认配置开箱即用,点开选一个即应用;选中方案后所有改动自动存入该方案,右侧「改名 / 导入 / 导出」管理方案(导出 JSON 分享、导入合并)。剪贴板不可用时(非安全上下文、或没有剪贴板权限)导出不会只给一段被截断的提示,而是把完整 JSON 放进一个已选中、只读的文本框,按复制快捷键即可,复制后自动收起;任何写设置失败(宿主拒绝、只读部署等)都会在当前行显示出来,而不是让控件悄悄弹回旧值;写入被接受、文档里的值却没有跟着变时,滑块也会在下方说明已回到文档里的值
  • 西文 / 中文分栏(简单模式) —— 编辑模式开关:简单模式每套字体只给「西文」「中文」两个单选格,高级模式是完整的字体栈编辑器;两种模式共用同一条栈,来回切换不改动已排好的顺序
  • 选字体面板 —— 内置 等宽 / 中文(CJK)/ 拉丁 / 通用 四组预设,Chromium 下再补上「本机已安装」分组;四组预设任何情况下都在(包括搜索时,也包括枚举本机字体失败时),本机分组只列出预设分组没有的字体,所以同一个字体不会出现两次;搜索不到的名字可以直接「使用 xxx」新建。字体枚举被浏览器拒绝时会在一段时间后自动重试(用户在浏览器里授予字体权限后,重新打开面板即可看到本机字体)
  • 拖拽排序 —— 已选字体是 chip 列表,可拖动调整回退顺序,同时保留前移 / 后移按钮(键盘与触屏可用)
  • 分区预览 —— 对话 / 界面 / 代码分区展开后在分区末尾各有一个预览框,只预览该分区的部分

兼容性

一份包同时支持三条宿主线——0.1.7-alpha.1 / alpha.2(下限)、0.1.7-rc.1 / rc.2、0.2.0-rc.1:安装方式与宿主线无关,三条线都验证过「设置卡片可用、样式真的作用到页面、卡片上的改动写得进去」。

插件版本 支持的 DSH 版本
0.3.x(最新,0.3.6) 0.1.7-alpha.1、0.1.7-alpha.2、0.1.7-rc.1、0.1.7-rc.2、0.2.0-rc.1、0.2.0-rc.2
0.2.x(0.2.8) 0.1.5-rc.3、0.1.7-alpha.1、0.1.7-alpha.2、0.1.7-rc.1、0.1.7-rc.2

每个大版本只列该系列最新的一个补丁版本(新功能引入的缺陷都在其后的补丁里修掉了,所以同一个大版本内直接用最新补丁即可;旧补丁仍可继续用,插件不破坏既有接口)。

安装

通过 DSH CLI 安装:

dsh plugin --profile web add dsh-fonttune

也可以从 GitHub 安装:

dsh plugin --profile web add github:LyaxZ/dsh-fonttune

或以本地目录安装:

dsh plugin --profile web add <插件目录路径>

安装后重启一次 DSH 并打开 Web UI;之后改设置不需要重启。

使用

  • 打开设置 —— 设置 → 插件 → 插件配置 → 展开「字体增强」卡片
  • 分区导航 —— 卡片展开后自上而下是:编辑模式、预设方案、对话 → 界面 → 代码三个收起的分区(对话在最前,因为它拥有全部轴),以及直接平铺在分区下面的「拒绝合成样式」;分区标题行右侧显示当前值摘要、箭头固定在最右,同一时刻最多展开一个分区
  • 换字体 —— 简单模式下点「西文/中文」格子选字体;高级模式下用「添加字体」与 chips 编辑器维护完整回退列表
  • 调整字号/字重/行高 —— 滑块就在各自分区里,拖动松手即生效(拖动时读数连同单位 % 一起显示);改过的字段标「已修改」并可单独重置,卡片底部有「全部重置」
  • 对话优先 —— 对话分区可以设置字体、字号、行高、字重四项;界面分区默认只有「跟随对话设置」开关(默认开启),关掉后才出现界面自己的字体与字重
  • 关掉跟随不会跳变 —— 关掉开关的那一刻,界面会把正在显示的字体与字重偏移写成自己的值(跟随期间它本来就是这两项),所以画面零变化、滑块从当前值继续调;对话没设的那一项则清掉界面自己的字段、保持 DSH 默认。想回到 DSH 自己的粗细点该项的「重置」(三个字重偏移读数都回到 0)
  • 界面字重不会碰到对话 —— 界面字重是唯一必须铺满整页的轴(DSH 把小标签的粗细写死在上游 CSS 的类规则里,窄规则够不到它),实现上是一条把对话 Markdown 整棵子树排除在外的规则,所以对话的段落、标题、粗体都不受影响
  • 字重读数 —— 三个字重轴的未设置读数都显示 0(滑块停在正中);不会出现「未设置」这类字眼;旧版本存的绝对字重(300 ~ 600)会在读取时自动换算成等价偏移(400 → 0、450 → +50),无需手动重设
  • 字重滑块按档计数 —— 卡片会量出当前字体在正文处能渲染出几档粗细,一档取变化足够明显的那一档(不是最细的那一档)、上下限以正文还能换字形为限(加粗与标题到顶后停住;读数就是档数,如 -1 … +2),所以档数可能比之前少、但每挪一格都看得出变化,也不会出现"几百几百"的数字;换字体后档数会重新测量
  • 预设方案 —— 编辑模式下方的下拉选择框(默认配置 1 ~ 5,框内右侧有与卡片一致的下拉箭头),点开选择即切换并自动保存后续改动;「改名」重命名当前方案,「导出」复制 JSON,「导入」粘贴合并。操作结果(如「已复制到剪贴板」)显示在下面那行的右侧,约 2.6 秒后自动淡出,不会顶动任何布局
  • 预览 —— 对话 / 界面 / 代码分区展开后,各自分区末尾有一个预览框,只渲染该分区的样式
  • 设置保存在 DSH 的设置文档里(0.1.7 起是 profile 的 cordis.patch.yml,更早的版本是 settings.yaml),跟随 profile 走

开发

  • src/shared.cjs —— 纯函数核心:字体名消毒与解析、配置归一化、注入样式的生成
  • src/index.mjs —— 宿主半:注册 dsh-fonttune 设置命名空间(schemastery schema,含长度与取值范围校验),并通过 webserver/index-inject 把一个打过标记的 <style> 随首页下发,首帧即是设置里的字体;那个元素随后由浏览器半认领并接管(页面里只有这一份样式表,规则可增可删)
  • src/client.js —— 浏览器半:设置卡片、选字体面板、字体枚举与样式注入
  • build.mjs —— 零依赖构建:内联共享核心、套上 window.__ModuleLoader__.load({id, factory}) 外壳、拷贝宿主半,并校验客户端 bundle 只 require shell 预注入的模块
  • test/run.mjs —— 离线检查(自建 DOM / cordis / 设置面替身、真实 schemastery schema、CSS 生成与注入、消毒对抗用例、双语文案键一致性、选字体面板的分组规则、令牌轮询的省电闸门);test/render-card.mjs 用 mini React hooks 运行时真实渲染卡片组件(含强制展开态与强制状态,覆盖 0.1.0 那类发布阻断崩溃),把每个控件的回调都点一遍(未接线的回调只有真点下去才会暴露),并渲染第二次覆盖「状态变化后 hook 顺序改变」这一类崩溃;test/artifacts.mjs 校验 lib/ 与当前 src/ 逐字节一致(npm run verify 跑全部三套)。devDependency 钉的是最新的 schemastery(^3.18.4),也就是 alpha 那套方言——它带 .volatile(),解析出来的字段是引用而不是值,所以这几套检查都通过宿主半导出的 plainConfigValue 取值(和插件读配置同一条路);运行时用的是宿主自带的那份(rc.2/rc.3 是 3.18.2,没有该修饰符,那条形态由真机探针覆盖)
  • 需要真实页面的检查走 npm run verify:browser -- "<带 token 的地址>"(先起一个受管实例:dsh web --port 0 --no-open,它会打印地址)。默认只跑只读的几支(browser-probe / ui-walk / host-line-probe / style-verify);加 --writers 再跑会写设置命名空间的几支(slider-walk / split-walk / split-verify / weight-verify,各自先快照用户层、退出前还原),--only a,b 挑子集;每支的退出码就是判定。test/set-user-layer.mjs <url> '<json>' 是在被中断的运行之后还原用户层的工具
  • test/host-line-probe.mjs 是与宿主线无关的那一支:只断言两条线都必须成立的事——页面无报错、插件只维护一份样式表、设置真的作用到文档(DFP_EXPECT_FAMILY / DFP_EXPECT_WEIGHT 给了就顺带断言计算样式)、设置页里能找到并渲染出 .dfp-card(哪条线的座位都行)、以及从卡片上改一个值真的写进去。换宿主线(rc ↔ alpha)后先跑它;调试「alpha 上卡片写不进去」这类问题时设 DFP_PROBE=1,插件会往控制台打一行 [dfp-probe](服务了哪些命名空间、认领了哪个、座位当前是什么状态)
  • test/weight-verify.mjs 在真实页面里量三条字重轴(界面 / 对话 / 代码)的独立性与「样式表只有一份、不刷新关掉跟随立即回落」,并逐级断言会话字重的阶梯(+180 与 −100 两个方向下 h2 > strong > 正文,且每组都等于自身基准 + 偏移);test/split-verify.mjs 量对话/代码两条字号轴的独立性、外加退役的界面字号轴什么都不动,并用一条 h1~h4 探针断言每个标题级别只吃一次偏移(±3 各验一遍,h1 > h2 > h3 ≥ h4);test/slider-walk.mjs 与 test/split-walk.mjs 驱动真实卡片(拖动不写、松手才写;简单模式两格与整条栈的往返);另有市场条目的维护脚本 test/market-pr.mjs(status / update / refresh / reopen / open / about)与诊断脚本 test/market-inspect.mjs(PR 状态、评论、CI 与分支差异)
  • docs/ —— 0.2.0 的背景调研与功能规格(设计阶段的记录,含当时的取舍理由;与最终实现不同的地方以 README/CHANGELOG 为准,两份文件文首都有说明)。不在 npm files 清单内,不随包发布
  • 客户端模块能 require 的只有 shell 静态表里的模块(react、react/jsx-runtime、react-dom、@deepseek-ai/cordis、@deepseek-ai/dsh-client-* 等);dsh.client.inject 只是加载顺序声明,不是 require 许可
  • 改完源码要先构建再刷新:node build.mjs(或 npm run watch)把 src/ 生成到 lib/,浏览器加载的是 lib/,只改 src/client.js 不构建的话页面看到的还是旧包;npm test 只检查功能,node test/artifacts.mjs(在 npm run verify 里)专门校验 lib/ 与当前 src/ 逐字节一致。改宿主半(src/index.mjs)或 cordis.patch.yml 需重启 DSH

License

MIT © 2026 LyaxZ

内容来自项目 README(GitHub)↗

评论

评论存放在 GitHub Discussions。用 GitHub 账号登录后可发表评论或点表情。