Impeccable typeset 排印命令全解:双轨评估、detect.mjs 机械扫描与类型系统落地
本文以 Impeccable 仓库中 typeset 命令的参考文档 typeset.md 为主体,完整展开其工作流:访问者模式判断、"设计评估 + 机械扫描"双轨隔离评估、类型系统声明、应用规则、验证清单与 Live 模式签名参数。读完你能掌握一套可复制的字体排印改进方法论,并能结合仓库中的源码、测试夹具与参数契约把它落到自己的前端项目中。
typeset 在 Impeccable 中的位置
Impeccable 是面向 AI 编码 Agent 的设计技能包,SKILL.md 中的 Commands 表将 typeset [target] 归类为 Enhance 命令,职责是"Improve typography hierarchy and fonts"(改进字体排印层级与字体),其参考文件即 reference/typeset.md。该文档在仓库中以三种形态存在,内容同源:
- skill/reference/typeset.md:源码模板,命令中使用
{{scripts_path}}占位符; - plugin/skills/impeccable/reference/typeset.md:插件打包版,使用
<skill-base-dir>占位符; - .opencode/skills/impeccable/reference/typeset.md:已按 OpenCode 安装路径展开的成品版,命令直接写作
node .opencode/skills/impeccable/scripts/detect.mjs。
文档开篇即给出核心原则,也是整篇参考的第一性约束:
Typography carries information, hierarchy, and voice. Improve it inside the established visual world; do not replace the identity unless the user asked to.
字体排印承载信息、层级与语气。应在既有的视觉世界内改进它;除非用户要求,否则不要替换产品身份。
这意味着 typeset 是"精炼型"而非"重建型"命令:既有的字体族、角色体系是被保护的既有事实,改进对象是"用法的正确性",而不是"换一套身份"。
Visitor mode:按访问者模式选择排印策略
文档第一节要求先判断界面的访问者模式,再决定排印策略。这与 SKILL.md 中定义的四种模式(Persuade / Operate / Read / Experience)一一对应,typeset 文档把它们压缩为三条策略线:
| 模式组合 | 排印策略 |
|---|---|
| Persuade + Experience(营销、作品集) | display 字体可以承载"声音"(voice);当构图受益时,使用果断的对比和响应式缩放 |
| Operate + Read(产品 UI、文档) | 稳定性、可扫描性、行长(measure)优先;通常"一个调校良好的字体族 + 固定的角色比例"就是正确解 |
| Native(iOS / Android) | 遵循 ios.md 或 android.md,包括平台缩放与无障碍行为 |
文档还划出了一条重要的边界:如果更换排印会构成一套新身份,必须改道到 new-work.md 流程并同步更新 DESIGN.md;否则保留已确认的字体族,只改进它们的使用方式。这条规则防止排印调优越权变成视觉重建,也与 SKILL.md 中 "Refinement preserves; redesign replaces" 的总原则一致。
Two isolated assessments:设计评估与机械扫描必须隔离
这是 typeset 工作流中最有方法论价值的部分。文档要求做两个相互隔离的评估:若子 Agent 工具可用且被允许,两者独立并行;否则按以下顺序自行执行。关键纪律是——不要让检测器的发现锚定(anchor)设计评估,即先凭机械规则下结论,会污染对排印质量本身的专业判断。
第一步:Typographic assessment(排印学评估)
检查代表性的页面与样式,且文档明确要求:下面每个问题都必须用"文件、选择器或计算值"作答,不接受空泛回答。
- Authority and fit(权威性与契合度):哪些字面(face)、字重、角色是既定的?它们契合产品与所选世界吗,还是未经审视的默认值?每个字体族都是必要的吗?
- Hierarchy(层级):标题、正文、标签、元数据、数据这些角色能否一眼区分?相邻的字号或字重是否过于接近、无法承担不同的工作?
- Scale and consistency(比例与一致性):存在深思熟虑的角色比例(role scale),还是一堆任意值?重复出现的角色在不同屏幕与状态下是否保持完全一致?
- Reading(阅读性):正文是否保持在舒适的 45–75 字符行长(measure)内?行高、段落节奏、对比度、字距是否针对实际的字体、宽度、语言与表面(surface)调校过?
- Stress(压力测试):遇到长标题、本地化文本膨胀、缩放、窄容器、缺失字重、字体回退时,会发生什么?
- Delivery(交付):是否只加载了用到的字体资产?回退指标、加载策略、可变字体设置是否避免了文字不可见(invisible text)和破坏性回流(reflow)?
第二步:Mechanical scan(机械扫描)
执行文档中给出的检测命令(.opencode 安装形态下的成品路径):
node .opencode/skills/impeccable/scripts/detect.mjs --json --scope type [target files or dirs]
--scope type 表示只运行与字体排印相关的规则族;--json 输出结构化结果供 Agent 解析。该检测器是随仓库分发的本地引擎,package.json 将 npm 包的入口指向 cli/engine/detect-antipatterns.mjs,且要求 Node.js >=22.18.0——运行 detect 前需要确认 Node 版本满足该前提。从仓库测试结构看,这套规则有对应的回归夹具支撑,例如 typography-should-flag.html(应命中)、typography-should-pass.html(应通过),以及 oversized-h1.html、extreme-negative-tracking.html、overused-font.html、undersized-ui-text.html 等针对具体排印反模式的单点夹具,可用于理解检测器"认为什么是问题"的边界。
评估完成后,文档还有两条收尾要求:
- 补检检测器读不懂的东西:动态或任意生成的字体值(如内联样式、JS 拼出来的字号),检测器无法解释,必须人工检查;
- 综合两份评估后再动手编辑,并记录"各自单独抓到了什么"。文档点明:一次干净的扫描只是下限(a floor),不是好排印的证明。
Set the system:编辑前先声明类型系统
文档要求在动任何代码之前,先显式陈述五项内容——这是一份"排印系统声明",等价于排印领域的技术方案评审:
- 界面需要哪些角色(roles);
- 这些角色之间预期的对比度;
- 阅读行长(measure)与密度;
- 哪些既有字体与字重是权威来源(authoritative);
- 存在的性能、本地化或无障碍约束。
随后文档给出两条设计判据:用最少的角色和字体族让层级变得无可置疑;刻意组合字号、字重、空间与语气,而不是让字号单独承担全部层级表达。最后一条容易被忽略但很重要:角色名和 token 应该描述用途而非数值——--text-body、--label-caption 优于 --fs-14、--w-500,因为后者在语义漂移时会诱导误用。
Apply:可直接执行的排印规则清单
文档的 Apply 一节是一份密度很高的实操清单,逐条继承如下,适合作为代码评审 checklist:
- 正文可读且可缩放。以
1rem/16px作为常规 Web 正文下限,除非高密度角色、平台惯例或用户设置另有正当理由。 - 散文控制在 45–75ch 之间。行高与行长反向调校:行越宽,通常越需要更多行距(leading)。
- 深色表面上的浅色文字要做三轴感知补偿:略微增加行高、略微增加字距、当字体需要时字重上调一档。这是补偿暗背景文字"视觉偏细"的经典手法。
- 行高按字体、宽度、语言、对比度调校,而不是套用某个"通用比例"。
- 重复角色跨屏幕、跨状态保持一致——同一角色的样式在任何地方都不应有漂移。
- 内容受益时启用特性开关:数字(
font-feature-settings: "lnum")、表格数字(tnum)、代码与标签类特性。 - 只加载用到的字体资产与字重;提供指标兼容(metric-compatible)的回退字体,避免阻塞文字渲染。
- 营销型 display 字体可以在有益时响应可用空间(如按视口缩放的 hero 标题);但密集产品界面与阅读表面要保持空间可预测。
- 保留浏览器缩放、用户字体设置、Dynamic Type 与平台文字缩放——排印改动不得破坏这些系统级行为。
- 段落节奏只用一种主手段:段间距(margin)或首行缩进二选一;两者同时使用通常会把段落边界"双重标记",造成视觉噪音。
清单后的总禁令:不要让排印以牺牲可理解为代价变成装饰;不要在没有"只有它能承担"的清晰角色的情况下引入第二个字体族。
Verify:以证据收尾并交接 polish
验证一节给出六条验收项,要求每一条都用渲染结果或源码证据作答,然后重跑一次机械扫描——"不要用一句空洞的 yes 替代验证":
- 主标题、次级标题、正文、元数据四种角色,在不读内容的前提下可被识别;
- 长文本在相关宽度与语言下依然舒适;
- 排印归属于该产品及其既定世界;
- 字体加载不产生破坏性回流或文字不可见;
- 缩放、文字放大、焦点、对比度、缩小视口等路径依然可用;
- 最终的机械扫描没有未解释的发现(unexplained findings)。
当层级站得住时,文档指定下一步是交接给 /impeccable polish 做发布前的最终质量通过——这与 SKILL.md 命令表中 polish 的定位("Final quality pass before shipping")闭环对应。
Live-mode signature params:变体模式下的排印参数契约
文档最后一节定义了 typeset 在 Impeccable Live 模式(浏览器内挑选元素、生成视觉变体)中的签名参数:每个变体都必须声明一个粗粒度 scale 参数,并针对 var(--p-scale, 1) 编写自己的类型比例阶梯:
{"id":"scale","kind":"range","min":0.85,"max":1.3,"step":0.05,"default":1,"label":"Scale"}
参数约束:
kind为range,取值范围0.85–1.3,步进0.05,默认1(即不缩放);- 类型阶梯必须写成对
var(--p-scale, 1)的响应,而不是硬编码字号,这样滑块调整时整套 ramp 同步缩放; - 最多再增加一个 pairing 或 weight 参数,且仅当它代表一个真实的系统级选择时;
- 其余参数约定遵循 live.md 的参数契约。
这条契约的意义在于:Live 模式生成的变体保持"一个旋钮控制整体缩放、至多一个真实设计决策"的极简参数面,避免变体空间失控。
小结:一份可复制的 typeset 工作流
把文档骨架串起来,typeset 的完整执行路径是:
- 定模式——Persuade/Experience 可放胆用 display 声音;Operate/Read 求稳;Native 走平台参考;身份级更换改道 new-work;
- 双轨评估——六问排印学评估(每问须给出文件/选择器/计算值)+
detect.mjs --json --scope type机械扫描,两者结论独立后综合; - 声明系统——角色、对比、行长密度、权威字体、约束五项先行;
- 应用清单——16px 正文下限、45–75ch、暗底三轴补偿、metric-compatible 回退、单一段落节奏等十条纪律;
- 证据化验证——六条验收项逐条给证据并重扫,干净后交接
polish; - Live 变体——
scale参数(0.85–1.3,step 0.05)驱动整条类型阶梯。
如需继续深入,可沿 SKILL.md 的命令表了解 typeset 与其他 Enhance 命令(layout、colorize、animate)的分工,或查看 tests/skill-reference.test.mjs 了解参考文档在 CI 中的校验方式。
atomcodeClaude Code 的开源替代方案。连接任意大模型,编辑代码,运行命令,自动验证 — 全自动执行。用 Rust 构建,极致性能。 | An open-source alternative to Claude Code. Connect any LLM, edit code, run commands, and verify changes — autonomously. Built in Rust for speed. Get StartedRust0627
Hy4-previewHy4 preview 是由腾讯混元团队研发的新一代混合专家(MoE)旗舰模型。模型总参数量 770B,每个 token 激活 49B,主干共包含78层,第一层采用标准 FFN,其余 77 层均为 MoE 结构,每层包含 256 个路由专家与 1 个共享专家,每个 token 激活 top-8 路由专家及共享专家。主干之外原生内置 1 层 MTP(总参数量 10B,激活 0.7B)以支持投机解码。Python00
GLM-5.3GLM-5.3 与 GLM-5.2 使用相同的基座模型——所有提升均来自后训练。与 GLM-5.2 相比,它在复杂编程和长程任务上的表现显著提升。Jinja00
GLM-5.3-FlashGLM-5.3-Flash (320B-A18B),是GLM-5系列的首个原生多模态模型。320B总参数,能力超过GLM-5.2Jinja00
Spark-X2.5-4BSpark-X2.5-4B 旨在让强大的 AI 更实用、更高效、更易获得。在广泛日常任务中表现强劲,涵盖对话、写作、翻译、推理、编码、工具调用以及智能体工作流,并在同等规模的开源模型中取得领先成绩。Spark-X2.5 将面向效率的架构与最高 1M tokens 的原生上下文窗口相结合,并支持 200 多种语言。Python00
Spark-X2.5-1.7BSpark-X2.5-1.7B 旨在让强大的 AI 更加实用、高效且易于获取。这些模型在广泛的日常任务中表现出色,涵盖对话、写作、翻译、推理、编程、工具调用和智能体工作流,并在同等规模的开源模型中取得领先结果。Spark-X2.5 将面向效率的架构与最高 1M tokens 的原生上下文窗口相结合,并支持 200 多种语言。Python00