OpenDesign Workflow
定位
把开源项目 nexu-io/open-design 的设计工作流搬到 WorkBuddy 对话里执行,产出的不是一段设计建议,而是可直接预览、可编辑、可继续迭代的单文件 HTML 产物。
核心不是「让模型画个页面」,而是给模型一套接近真实产品团队的设计纪律:先锁定决策 → 再定义结构与路径 → 最后进入视觉表达 → 交付前用机器规则和评分卡自检。
来源与许可:skills/design-brief、skills/frontend-design、craft/ 等为 Apache-2.0;craft/ 内容源自 MIT 的 referodesign/refero_skill,本 Skill 做了改写与本地化(补入 CJK 排印规则、把 daemon linter 重写为独立 Python 脚本)。使用或二次分发时保留上述署名与许可说明。
与工程流程的分工
本 Skill 负责设计质量链路:brief → DESIGN.md → 产物 → linter → 五维评分。
研发阶段划分、独立代码评审、测试设计与历史用例回归由 ai-go-dev 编排(其 §3.4 定义了本 Skill 各步骤对应的阶段门禁)。
两者同时可用时:设计口径以本 Skill 为准,工程与评审流程以 ai-go-dev 为准;本 Skill 的 linter P0/P1 记录为「设计产物-P0/P1」,与代码评审的「评审-P0/P1」不互换、不互相抵扣。
何时触发
- 要求做网页 / 原型 / 仪表盘 / 移动端界面 / 落地页 / 演示稿 / UI 改造 / 视觉稿。
- 要求生成或修改
DESIGN.md、设计系统、品牌 token。 - 要求审查已有页面的「AI 味」、设计质量、视觉一致性、可访问性。
- 已有 HTML 产物,要求局部调整或打磨。
不触发:纯代码实现(业务逻辑、接口、数据管道)、需要 Figma 源文件或设计稿交付、需要 OpenDesign 云端协作与分享链接的场景(那些依赖其桌面端/daemon,本 Skill 不代理)。
工作流决策树
| 用户诉求 | 进入路径 |
|---|---|
| 从零做一份设计产物 | Step 1 → 2 → 3 → 4 → 5 → 6 → 7(全流程) |
只要 DESIGN.md / 设计系统 |
Step 1 → 2,然后交付,不生成 HTML |
| 只做审查或去 AI 味 | 读现有文件 → Step 5 → 6 → 迭代模式 |
| 在已有产物上改局部 | 迭代模式(不重生成) |
Step 1 · 锁定 brief
读 references/brief-protocol.md,把用户的自然语言需求解析成 8 个离散维度:palette / accent / typography / display / layout / mood / density / exclude。
- 值必须落在闭集内;用户给出闭集外的值时,列出最接近的候选请其确认,不猜。
- 未指定的维度按缺省规则解析,并在最终回复中逐条列出「维度 = 值(规则:…)」。静默假设会一路传播到 HTML,是后续返工的主要来源。
- 需求明显不足时,一次性给出最多 4 个关键选择(目标用户、场景、调性、品牌上下文),带推荐缺省;不要挤牙膏式反复追问。
- 同时确认:目标平台、受众、核心任务、禁用项、是否有既有品牌资产或
DESIGN.md。
Step 2 · 建立 DESIGN.md 单一事实源
读 references/design-md-spec.md,按九段结构输出,并把 Step 1 的符号值解析成具体色值、字族、间距 token。
- 工作目录已有
DESIGN.md→ 直接读取复用,不得覆盖;需要调整时先给 diff 和影响范围。 - 用户提供的品牌色/字体/截图优先于缺省色板。
- 渲染阶段只允许引用
DESIGN.md声明的 token,裸 hex 只允许出现在:root。
Step 3 · 先定信息架构,不先画像素
在写 CSS 之前明确并记下:目标用户与主要任务、信息层级、页面/屏幕清单、关键用户路径、每屏唯一的主任务、真实内容来源。
- 数据未知时写成明确标注的占位(
—/待接入),不编造指标。 - 至少安排一个非常规区块,避免
Hero → Features → Pricing → FAQ → CTA的模板骨架。 - 有状态 UI 先列出需要覆盖的状态(默认 / hover / focus / active / disabled / loading / empty / error / success)。
Step 4 · 生成单文件 HTML 产物
复制 assets/artifact-skeleton.html 作为起点,用 Step 2 的 token 填满 :root,替换各 section 内容。
- 骨架已通过自带 linter,保留其语义结构、状态类、
data-od-id、:focus-visible、prefers-reduced-motion与 CJK 行高设定。 - 产物必须自包含:内联 CSS/JS、无外部 CDN、无外部字体强依赖、可直接双击打开。
- 每个主要区块保留
data-od-id,供后续评论与增量修改定位。 - 按
references/craft-rules.md处理排印、色彩配额、状态与可访问性。中文产物尤其注意:展示标题line-height1.3–1.4(大字号无豁免)、正文 1.7–1.8、负字距只用于拉丁文本、ALL CAPS 字距 ≥0.06em。 - accent 每屏可见使用不超过 2 次;图标用单线 SVG 而非 emoji。
Step 5 · 机器自检(硬门槛)
python3 <skill-dir>/scripts/lint_artifact.py <artifact.html>
python3 <skill-dir>/scripts/lint_artifact.py <artifact.html> --strict --json
脚本把 OpenDesign daemon 的 P0/P1 检查重写为独立静态检查:默认 indigo、两色信任渐变、emoji 图标、标题绕过 display 字体、圆角磁贴、编造指标、假文案、占位图 CDN、token 泄漏、accent 过密、CJK 行高、区块 id、焦点样式、减弱动效回落。
- P0 必须清零后才可交付,不得以「风格偏好」豁免。
- P1 逐条判断:确有正当理由时,在交付说明里写明规则号与理由;否则修复。
- 退出码 1 表示存在必须修复的 P0(或
--strict下的 P1);--json便于把结果并入自动化流水线。
Step 6 · 五维自评审
读 references/review-rubric.md,对信息层级、交互一致性、可读性、适配能力、视觉完成度逐维打 1–5 分,每条扣分给出 file:line 级证据。
- 任一维 < 3 分必须实际改文件后重评,不能只写「下次改进」。
- 返工只改被扣分的区块与对应 CSS,保留用户未要求改的内容。
- 重跑 linter,确认修复没有引入新的 P0。
Step 7 · 交付
- 调用产物预览,让用户直接看到成品(单文件 HTML 打开即可)。
- 回复中给出:产物路径、
DESIGN.md路径、linter 结果、五维评分、未指定维度及采用的缺省规则、验证步骤。 - 总结保持简洁,不逐段复述文件内容。
迭代模式(只改局部时)
先读现有产物 → 把范围收敛到用户点名的区块 / 元素 / 规则 → 做几个决定性修正,不做大范围美容式重写 → 只对该文件重跑 linter → 说明改了哪些 data-od-id、未改哪些。保留既有内容与品牌设定。
资源索引
| 文件 | 用途 | 加载时机 |
|---|---|---|
references/brief-protocol.md |
8 维度闭集、自然语言映射、token 解析表、缺省规则 | Step 1 |
references/design-md-spec.md |
DESIGN.md 九段契约、CSS 变量命名、不覆盖原则 | Step 2 |
references/craft-rules.md |
P0/P1/P2 反 AI 味规则、色彩配额、CJK 排印、状态与可访问性 | Step 4 |
references/review-rubric.md |
五维评分卡、返工判据、交付清单、迭代模式 | Step 6 |
scripts/lint_artifact.py |
可执行静态检查(P0/P1/P2),无第三方依赖 | Step 5、Step 6、迭代后 |
assets/artifact-skeleton.html |
通过 linter 的单文件 HTML 起点 | Step 4 |
附:通用排障纪律(强制,跨项目)
适用于本 Skill 执行过程中的任何失败、异常与缺陷结论——包括 linter 报错、产物渲染异常、预览打不开、样式未按预期生效、脚本退出码非 0。
禁止用现象复述冒充根因。 「X 未产生 / X 失败 / X 被跳过 / X 缺失」这类表述只是把观测到的现象换了个说法,不算定位。任何故障/异常结论必须回答「为什么会发生这一步」,否则判本次定位未完成。
判据与写法:
- 三层结构:现象(观测到什么)→ 直接原因(哪个分支没进/走错,带 文件:行号)→ 根因(为什么会进这个分支,带触发条件 + 上游来源)。
- 根因三件套,缺一只能标【现象】:① 代码位置 ② 日志证据原文(取不到写【无日志·待补】)③ 触发条件。
- 拿到直接原因后至少再问一层 Why,直到落到:可复现的具体输入/配置,或已确认的代码缺陷,或【未确认】+ 待取证据清单。
- 追不动就如实标【未确认】,不许用推测填空。
- 禁止空话:「链路有问题 / 上游异常 / 服务处理失败」这类无主语、无位置的表述一律作废重写。
例如,不允许写「linter 没检查出问题」就收尾;必须写清是 lint_artifact.py:NN 的哪条规则未命中、输入文件的哪一行为什么不满足该规则的匹配条件,以及这个条件由 Step 4 的哪个具体写法引入。