1实现原理 · 为什么它能做到
这个 skill 不是可执行程序,而是「一个目录 = 一个模板」:SKILL.md 的 frontmatter 供选择器展示,正文(body)就是发给模型的提示词;加模板=加目录,不需要改 TypeScript。
routes rescan disk and the client refetches `/api/templates`.
实际下发提示词 = 平台共享设计指令(SHARED_DESIGN_DIRECTIVES)+ 本 skill 的 SKILL.md 正文 + 用户内容,由 assemblePrompt 拼成一条 prompt。
Wrap a per-template instruction body with the shared design directives and
成稿不走文件系统:共享指令明令禁止 Write/Edit/Bash 等文件工具,要求模型把整份 HTML 直接作为回复正文流式输出(stdout 由前端捕获落盘)。
**禁止使用 Write / Edit / MultiEdit / Bash / Create / 任何文件系统工具**。不要把 HTML 写到任何 \`.html\` 文件里。前端直接捕获你的 stdout 文本, 文件落盘由前端负责。
目标是「能进邮件客户端的 HTML」:SKILL.md 规定 600px 单栏、用 <table role='presentation'> 兜底布局、颜色走 inline style 而非 class。
- 使用 `<table role='presentation'>` 做布局兜底
平台侧的落地链路正好解释「为何必须内联样式」:导出微信/邮件时,前端用 juice 把 <style> 里的 CSS 内联进每个元素,因为目标客户端只认行内样式。
Take a full HTML document, extract <body> content, inline all CSS via juice,
邮件结构按发布邮件范式铺满:Masthead(wordmark + 导航)→ Hero 图块 → Headline lockup(含斜切 accent)→ 正文 → 主 CTA 按钮 → 规格网格 → 页脚(社交 + 退订)。
<div class="frame" data-od-id="email">
Hero 是内联 SVG 绘制的产品图(一双跑鞋),不依赖外链图片——多段 path + 两个 linearGradient 上色。
<svg class="shoe" viewBox="0 0 600 280" aria-hidden="true">
品牌调子的抓手是「斜切元素」:wordmark 的 accent 方块 transform: skew(-12deg),标题里的强调词 skew(-8deg) 斜体,形成运动品牌的动感语汇。
h1.lockup .axis { color: var(--accent); display: inline-block; transform: skew(-8deg); }
转化闭环写进页脚:Unsubscribe + View in browser 两条合规链接与版权行。
<div><a href="#">Unsubscribe</a> · <a href="#">View in browser</a></div>
服务端 /api/convert 只做三件事:按 templateId 从磁盘读 skill、拼 prompt、spawn 本地 agent CLI 并 SSE 流转发输出。
prompt = assemblePrompt({ body: skill.body, content, format });
2核心能力
4风险提醒 风险提醒:绿色 · 放心使用
- 提示词承诺的兼容性手法未在样例落实 — table 兜底与 inline style 是邮件兼容的关键,样例两条都没做;若模型照样例产出并直接投递,在 Outlook 等客户端可能掉样式(依赖宿主 juice 补救)。
- 宽度不一致 — aspect_hint 写 600、样例 680,而响应式断点在 540px;邮件模板宽度关系到移动端换行与图片尺寸,需在成稿时统一。
- 占位链接与虚构品牌 — 页脚 Unsubscribe/View in browser 与导航均为 href="#",直接投递等同缺少退订入口(合规风险);品牌名/地址均为样例虚构内容,不可直接沿用。
- 注入面 — 用户内容逐字进 prompt;邮件 HTML 属会被大量客户端渲染的载体,若用户内容带入脚本/外链,成稿可能在收件人侧执行或追踪。
5第二遍独立确认
- [discrepancy] 「600px 单栏」 — 样例 .frame { max-width: 680px; },为 680px(frontmatter aspect_hint 也写「600 邮件宽」);单栏成立,宽度不符。
- [discrepancy] 「使用 <table role='presentation'> 做布局兜底」 — 样例全文无 <table>、无 role="presentation",改用 <div class="frame"> + grid/flex;邮件客户端(Outlook)对 grid 支持差,规范与样例的兼容性结论相反。
- [discrepancy] 「颜色用 inline style (不要依赖 class)」 — 样例把配色写在 <style> 的 :root 变量与 class 里,仅个别元素用 inline style;与规范相悖(宿主可用 juice 内联补救,但那是导出期行为)。
- [discrepancy] 「Specifications grid (3 列)」 — 样例 .specs-grid 为 repeat(2, 1fr),且实际 4 个 .spec(2 列 × 2 行)。
- [discrepancy] 「Masthead (wordmark 居中)」 — 样例 masthead 为 display:flex; justify-content: space-between,左侧 wordmark + 右侧 SHOP/JOURNAL/MEMBERS 导航,非居中。
- [ok] Hero 为 SVG 占位而非外链图 — <svg class="shoe" viewBox="0 0 600 280"> 含两条 linearGradient 与多段 path,无 <img>。
- [ok] 目录内零脚本/零端点 — 无 <script>、无 CDN、无字体外链;字体族名属本地/系统栈。
6结论
ed93a7856ba23d50…553ed98c28