LifeOS HTML Skill 实战解析:用确定性渲染器把会话产出蒸馏为自包含 HTML Artifact
【免费下载链接】LifeOS⛰️ The Life Operating System — an intent engineering platform that moves you from your current state to your ideal state, in life and work.项目地址: https://gitcode.com/GitHub_Trending/pe/LifeOS
导读
LifeOS 的 HTML 技能(位于 LifeOS/install/skills/HTML/SKILL.md)解决一个具体问题:把模型会话刚刚产出的分析、研究、红队报告、计划等内容,一键变成一份"设计精良、完全自包含、可发布为 Artifact"的 HTML 文件。其核心是一套确定性分工:模型只负责把会话内容蒸馏为类型化的 content JSON 并挑选一种设计寄存器(register),而 Tools/Render.ts 独占所有布局、排版与配色决策。读完本文,你将掌握该技能的内容 JSON Schema、dossier/ledger双寄存器机制、Render 工作流的完整调用契约,以及它在 Artifact-CSP 约束下的五项工程教训。
一、技能定位与触发边界
技能 frontmatter(SKILL.md第 1–5 行)给出了明确的触发契约,这是所有 LifeOS 技能共用的路由机制(命名、frontmatter、渐进式披露规范可参考 CreateSkill/SKILL.md):
- 触发词(USE WHEN):
/HTML、HTML artifact、render this as HTML、make this an HTML page、artifact of this analysis、designed HTML output; - 明确不适用(NOT FOR):部署型网站或 Web 应用(应直接搭建项目)、Web UI 设计系统(用 Webdesign 技能)、静态图片或图表(用 Art 技能)、以及撰写底层分析本身(先跑分析,再用 /HTML 渲染它)。
技能的职责一句话概括:"把会话刚产出的任何内容变成一个自包含、有设计感的 HTML 文件,并发布为 Artifact"。
1.1 目录结构与安装形态
在仓库中该技能由三个文件构成:
| 文件 | 作用 |
|---|---|
| SKILL.md | 技能路由入口:触发词、工作流路由表、快速参考、Gotchas、示例 |
| Workflows/Render.md | Render 工作流:充分性检查、工具契约、发布与验证双腿 |
| Tools/Render.ts | 确定性渲染器:读入 content JSON + register,输出单文件 HTML |
安装到用户环境后,路径为~/.claude/skills/HTML/(命令示例中即使用该形态)。注意整个技能树遵循 CreateSkill 的扁平结构约定:SKILL.md只做路由与要点,完整 SOP 放在Workflows/,可执行脚本放在Tools/。
1.2 Voice Notification 双通道
执行任何工作流前必须先发送两条通知(这是 LifeOS 全部技能的强制约定):
curl -s -X POST http://localhost:31337/notify \ -H "Content-Type: application/json" \ -d '{"message": "Running the Render workflow in the HTML skill to build a designed HTML artifact"}' \ > /dev/null 2>&1 &同时输出文本通知:Running **Render** in **HTML**...。这是 LifeOS 语音/文本提醒体系的统一接入点,与 CreateSkill、Interceptor 等技能的模式完全一致。
二、核心架构:模型与渲染器的确定性分工
HTML 技能的设计哲学(SKILL.md第 9 行)可以概括为一条铁律:
模型的唯一职责是把会话输出蒸馏为类型化 content JSON 并挑选设计寄存器;Render.ts 拥有所有布局、排版、配色决策。
这条边界带来三个直接收益:
- 输出可复现:同一个 content JSON + 同一寄存器,永远渲染出同一份 HTML,不存在"这次好看下次难看"的模型抖动;
- 提示词成本低:模型不需要理解 CSS,只需把内容正确归类到 Block 类型;
- 易于演进:想改样式只需改 Render.ts 一处,所有历史工作流自动受益。
源码开头的注释( 其中 寄存器是"设计模板"的载体,定义在 面向证据文件、红队、调查、主张测试: 面向报告、财务、计划、对比、指标: 工作流( 最后一条规则很有工程味道:"在它们之间交替使用,避免连续产出视觉趋同(converge)"( Workflows/Render.md 定义了从"会话产出"到"已发布、已验证的 HTML Artifact"的完整路径。 渲染前先确认有实质内容可渲染:如果会话尚未产出任何可渲染输出(没有分析、研究或成果),应直接说明并询问要渲染什么,绝不虚构内容。若存在多个候选输出,必须明确标记选择了哪一个( Render.ts 是一个标准的 Bun 可执行脚本(shebang 内容校验(第 282–286 行):JSON 至少需要 CSS 伪元素生成的内容(counters、 这条教训在仓库内得到了第二处独立佐证:Interceptor 技能的 Gotchas 区块记录了一模一样的观察( Artifact 环境会静默拦截外部资源:一个 Google Fonts 的Render.ts第 3–19 行)把这一意图写得非常明确:"Takes a typed content JSON + a design register name, emits ONE self-contained HTML file: inline CSS, optional @font-face>interface Doc { title: string; // 页面 + 报头标题;accentLastWord 为真时末词渲染为强调色 eyebrow?: string; // 眉题(小号等宽大写文本) subtitle?: string; // 副标题 accentLastWord?: boolean; // 默认 true summary?: { label?: string; html: string }; // 顶部摘要块(slab) sections: Section[]; // 章节数组 footer?: string; // 页脚备注 numberedSections?: boolean; // 默认 true —— 章节编号以真实文本渲染 } interface Section { title: string; intro?: string; blocks: Block[] }blocks是七种可判别联合(discriminated union)类型,每种对应一种渲染形态(renderBlock实现见Render.ts第 167–201 行):Block 类型 字段 渲染形态 对应 CSS 类 prosehtml正文段落(最多 62ch 宽) .prosecallouthtml强调提示框(左边框使用 accent2) .calloutgrouplabel,detail?时代/类别分隔标记(等宽大写) .groupquoteid?,badge?,quote?,text?,note?,source?证据条目:编号 + 徽章 + 引言/正文/备注/来源 .exlistitems: { lead, text }[]粗体引导语列表(仅当内容是真正的序列时才编号) ul.leadcutstamp,quote,note删除线引言 + 旋转印章(用于披露被否决的内容) .cuttableheaders: string[],rows: string[][]数据表(响应式横向滚动包裹) .tablewrap3.1 关键字段语义
quote的badge是自由文本(如VERIFIED、REPORTED、FACT),由寄存器的badgeSolid数组决定是实心填充还是描边轮廓渲染(Render.ts第 176–178 行);01、02……用String(i+1).padStart(2,"0")补零,见Render.ts第 212 行),绝不使用 CSS counters——这是下文的头号 Gotcha 的规避方案;title的最后一个词默认以强调色渲染(<span class="acc">,见Render.ts第 203–207 行),accentLastWord: false可关闭。四、双设计寄存器:dossier 与 ledger
Render.ts第 61–86 行的REGISTERS常量中。每个寄存器由 CSS 变量(颜色体系)、三段字体栈(display/body/mono)、可嵌入字体与实心徽章列表构成。4.1 dossier 寄存器(证据卷宗风)
项 值 背景 --ink#0d1712(深墨绿)面板 --panel#121f17分隔线 --line#26382c前景 --fg#f2ede2(米白)次要 --dim#c6c0b1强调 --accent#f58220(橙色)辅助 --accent2#7d9fc4危险 --danger#d0654a展示字体栈 Anton, 'Arial Narrow', 'Avenir Next Condensed', sans-serif(压缩大标题 + 打字机感)正文字体栈 'Avenir Next', 'Helvetica Neue', system-ui, sans-serif等宽字体栈 'Courier New', monospace嵌入字体 Anton-Regular.ttf(从本地字体目录查找,命中即 base64 嵌入)实心徽章 VERIFIED4.2 ledger 寄存器(账册报表风)
项 值 背景 --ink#101623(深藏青)面板 --panel#161e30分隔线 --line#2a3550前景 --fg#dce6f2次要 --dim#9fb0c8强调 --accent#d9a441(金色)辅助 --accent2#6fbf9f危险 --danger#c96f6f展示字体栈 'Iowan Old Style', 'Palatino', Georgia, serif(古典衬线)正文字体栈 'Avenir Next', 'Helvetica Neue', system-ui, sans-serif等宽字体栈 'SF Mono', Menlo, 'Courier New', monospace嵌入字体 无(依赖系统栈) 实心徽章 VERIFIED、CONFIRMED4.3 寄存器使用规则
Render.md第 39–45 行)给出明确的选型表:内容类型 寄存器 证据文件、红队、调查、主张测试 dossier报告、计划、对比、指标、财务 ledger本周上一个 Artifact 用了同一个寄存器 选另一个 SKILL.md第 38 行)。新增视觉风格的正确姿势是在 Render.ts 中扩展新寄存器,而不是为一次性需求手写样式(one-off CSS),这样后续每次运行都能复用。4.4 字体嵌入机制
fontFace(Render.ts第 96–110 行)实现了零外部请求的字体方案:在FONT_DIRS(~/Library/Fonts、/Library/Fonts、/System/Library/Fonts/Supplemental,第 88 行)中按序查找寄存器的字体文件,命中第一个存在的文件即读取为 base64 生成@font-facedata URI(.otf声明为opentype,其余按truetype),font-display: swap保证加载不阻塞;找不到则静默降级到系统字体栈。五、Render 工作流完整实战
5.1 Step 0 —— 充分性检查(第 16–18 行)
⚠️ Rendering X, not Y; redirect if wrong.)再继续。5.2 Ideal State(第 20–24 行)
5.3 工具契约(第 26–35 行)
bun ~/.claude/skills/HTML/Tools/Render.ts --schema # 打印 content JSON 结构 + 示例 bun ~/.claude/skills/HTML/Tools/Render.ts --registers # 列出可用寄存器 bun ~/.claude/skills/HTML/Tools/Render.ts \ --json <content.json> \ --register <dossier|ledger> \ --out <artifact.html>5.4 发布 + 验证双腿(第 47–53 行)
artifact-design技能(任何 Artifact 发布前的强制前置),再用 Artifact 工具发布渲染好的文件;复用同一文件路径即可更新既有 Artifact 的 URL;list动作能看到该 Artifact;bunx serve)打开 HTML 文件,用 Interceptor 技能的规范截图路径捕获并查看像素——因为 Artifact URL 在任何未登录属主账号的浏览器会话中会 404(详见 Gotchas);六、CLI 手册:参数、默认值与校验逻辑
#!/usr/bin/env bun),CLI 解析逻辑在第 255–289 行:参数 默认值 行为 --schema— 打印 EXAMPLE文档 JSON(含七种 Block 的示例用法)后退出(第 261–263 行)--registers— 逐行打印寄存器名( dossier、ledger)后退出(第 265–267 行)--json <path>必填 读取 content JSON;缺失时打印 Usage 并以 exit 2 退出(第 273–275 行) --register <name>dossier按名字查 REGISTERS;未知寄存器打印可用列表并以 exit 2 退出(第 277–281 行)--out <path>artifact.html输出文件路径 { title, sections[] },否则报错提示用--schema查看示例。渲染成功后(第 287–289 行)打印产物信息:artifact.html (NKB, register=dossier, fonts=Anton|system)——其中fonts段会报告实际嵌入的字体族,无嵌入时为system,可用于确认字体嵌入是否生效。七、Gotchas:Artifact 渲染的五个工程教训
SKILL.md第 41–47 行的 Gotchas 区块是全技能信息密度最高的部分,全部来自真实踩坑记录(其中第一条的发现日期标注为 2026-07-11)。这五条对任何做 Artifact/CSP 安全 HTML 输出的开发者都有直接参考价值:7.1 伪元素生成内容会在 DOM 渲染截图管线中消失
::before标签)在浏览器里正常渲染,但从 DOM 渲染的截图中消失,且对文本提取不可见。因此 Render.ts 把所有编号和标签都输出为真实 DOM 文本。绝不向寄存器中添加 CSS counters。LifeOS/install/skills/Interceptor/SKILL.md):"DOM-render screenshots drop CSS pseudo-element generated content.::before/::aftercontent — CSS counters especially — renders in the live browser but vanishes from the default DOM-render capture, so a page can look broken in the screenshot while fine on screen."也就是说,这不是 HTML 技能独有的怪癖,而是该截图技术路线的系统性行为——HTML 技能选择从源头规避。7.2 Artifact 阻断一切外部请求
<link>会悄悄失败,页面回退到系统字体栈。正确做法是 contenteditable="false">【免费下载链接】LifeOS⛰️ The Life Operating System — an intent engineering platform that moves you from your current state to your ideal state, in life and work.项目地址: https://gitcode.com/GitHub_Trending/pe/LifeOS
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考