codify-design-to-code

Installation
SKILL.md

Codify Dev - 设计转代码

核心原则

截图看布局,骨架定边界,JSON 取样式。三者协同,缺一不可。

结构先行,样式后填。 你看不到渲染结果,所有布局正确性只能靠推理。先用截图和骨架确定正确的 DOM 结构,再用 JSON 填充精确样式值。结构错了,样式再精确也白费。

数据源 告诉你什么 不告诉你什么
截图 视觉效果、颜色感知、间距比例、整体氛围 精确数值、层级结构、节点 ID
骨架 组件边界、布局方向、重复模式、节点层级 具体样式、颜色、字体大小
JSON 精确 CSS 值、节点属性、资源 ID 视觉上下文、设计意图

协同:截图 + 骨架 → 理解意图、确定 DOM 结构;骨架 + JSON → 精确实现;截图 + JSON → 验证还原。


工作流程

准备:设置工作目录

每次任务开始时先执行,用节点 ID 隔离临时文件,避免并发冲突:

SKILL_DIR="/path/to/skill"                    # 替换为 skill 目录实际路径
NODE_ID="节点ID"                               # 替换为实际节点 ID
FILE_KEY="文件Key"                             # 替换为实际文件 Key
WORK_DIR="$TMPDIR/codify-${NODE_ID//:/–}"     # 每个节点独立目录
mkdir -p "$WORK_DIR"

SKILL_DIR 通常为当前 skill 文件所在目录,如 /Users/xxx/project/skill


Step 0. 获取截图,建立视觉基准

截图是第一步,不可跳过。 在读骨架和 JSON 之前先看截图,用于:

  • 识别所有视觉元素(装饰图形、渐变、光晕等)
  • 建立视觉基准,后续所有 JSON 解读都以截图为参照
node "$SKILL_DIR/scripts/download-screenshot.cjs" \
  --nodeId "$NODE_ID" \
  --fileKey "$FILE_KEY" \
  --output "$WORK_DIR/screenshot.png"

截图下载后立即读取图片,记录:

  1. 页面整体布局和层次
  2. 所有视觉装饰元素(光晕、阴影、渐变、图标)
  3. 文字样式的视觉重量和颜色
  4. 哪些元素突出了其父容器的边界(如图标超出卡片顶部、阴影溢出容器等)

Step 1. 获取骨架,理解结构

curl -s -X POST http://127.0.0.1:13580/get_design \
  -H "Content-Type: application/json" \
  -d "{\"node_id\": \"$NODE_ID\", \"file_key\": \"$FILE_KEY\", \"mode\": \"skeleton\"}"

对照截图阅读骨架,重点关注:

  • 整体层级和布局方向
  • 与截图对应的视觉元素是否都在骨架中有对应节点
  • 组件边界和重复结构

骨架标记见 design-schema.md,拆分规则见 codegen-rules.md

判断复杂度,选择路径

条件 路径 说明
骨架层级 ≤ 3 层,且带 ID 的子节点 ≤ 3 个 快速路径 直接获取完整 JSON 一次性生成
骨架层级 > 3 层,或带 ID 的子节点 > 3 个 分块路径 按区块逐块实现再组合

判断标准不是绝对的:如果骨架虽然层级多但节点重复度高(大量 ×N),仍可走快速路径。关键是你能否在一次生成中准确记住所有节点的精确样式值。如果不确定,选分块路径。


Step 2A. 快速路径:一次性获取 JSON + 生成

适用于简单 UI(少量节点、浅层级)。

获取完整 JSON 并保存:

curl -s -X POST http://127.0.0.1:13580/get_design \
  -H "Content-Type: application/json" \
  -d "{\"node_id\": \"$NODE_ID\", \"file_key\": \"$FILE_KEY\"}" \
  > "$WORK_DIR/design.json"

# 读取(小型节点直接格式化输出)
cat "$WORK_DIR/design.json" | python3 -m json.tool

识别并下载所有资源:

JSON 返回的数据中有两类资源需要下载,它们的发现机制不同:

  1. assets 数组中列出的矢量资源:JSON 末尾的 assets 数组明确列出了所有 ICON / VECTOR 类型节点,可直接按 nodeId 批量下载为 SVG
  2. 主结构中的位图资源RECTANGLE / IMAGE 类型且带有 object-fit 属性的节点是位图填充节点,不会出现在 assets 数组中,需要从主结构中识别后单独下载为 PNG

建立节点→用途的映射:下载前,必须将每个资源节点的 nodeId 映射回主 JSON 结构树中,通过该节点在结构树中的**位置(父子层级、相邻节点)**来确定它的 UI 角色(如关闭按钮、装饰图标等)。不要凭节点的 typename 猜测用途。

node "$SKILL_DIR/scripts/download-assets.cjs" --fileKey "$FILE_KEY" --nodes '[
  {"nodeId":"<nodeId>","outputPath":"$WORK_DIR/icon-name.svg","format":"svg"}
]'

⚠️ 关键规则:ICON / IMAGE 节点必须下载实际资源文件,代码中直接引用文件路径。不要跳过下载自己画 SVG,也不要用占位符,也不要用 Unicode 字符近似替代。

然后跳到 Step 4. 生成代码


Step 2B. 分块路径:制定分块计划

适用于复杂 UI(深层级、多节点)。

根据骨架结构,将设计拆分为 3-6 个独立区块。每个区块对应骨架中一个带 ID 的子树。

分块原则:

  1. 每块对应截图中一个视觉区域
  2. 每块的 JSON 数据量在一次上下文中可完整消化
  3. 块之间通过容器布局关系组合,互不依赖内部细节

记录分块计划(示例):

Block A: 25:05110  → 卡片容器 + 装饰光晕 + 关闭按钮
Block B: 25:05123  → 盾牌图标 + 标题
Block C: 25:05133  → 步骤图标列(左侧)
Block D: 25:05134  → 步骤内容列(右侧)

Step 3. 分块路径:逐块执行

对每个 Block 重复以下三步,完成一个块后再开始下一个:

3.1 获取该块的 JSON

curl -s -X POST http://127.0.0.1:13580/get_design \
  -H "Content-Type: application/json" \
  -d "{\"node_id\": \"子节点ID\", \"file_key\": \"$FILE_KEY\"}" \
  > "$WORK_DIR/block-A.json"

cat "$WORK_DIR/block-A.json" | python3 -m json.tool

读取 JSON 时必须做到:

  1. 子节点 customStyle 全量读取:不只读顶层节点,对每一个子节点都读取 customStyle,尤其关注:

    • margin-top / margin-bottom / margin-right / margin-left:决定元素间距,是布局精确度的关键
    • padding:决定容器内边距
    • align-items / justify-content:决定对齐方式
  2. 布局模式判断:遇到并排/堆叠结构,明确区分:

    • 左列是弹性伸缩flex:1)还是固定尺寸堆叠(固定 height + margin-bottom)?
    • 判断依据:子节点是否有固定 width/height + margin-bottom,如有则用固定尺寸,不用 flex:1 估算
  3. JSON 必须读完:如数据较大需分段读取,须确认读到最后一段才进入下一步

3.2 下载该块涉及的资源

资源的发现和识别规则:

  • 矢量资源:从 JSON 末尾的 assets 数组中,筛选出 nodeId 属于当前块子树的条目,批量下载为 SVG
  • 位图资源:在当前块的 JSON 结构中,查找带 object-fit 属性的 RECTANGLE / IMAGE 节点,单独下载为 PNG

命名依据结构位置而非猜测:资源文件的命名应基于该节点在结构树中的 UI 角色(通过父子层级和相邻节点判断),而不是基于节点的 typename 字段。

node "$SKILL_DIR/scripts/download-assets.cjs" --fileKey "$FILE_KEY" --nodes '[
  {"nodeId":"<nodeId>","outputPath":"$WORK_DIR/icon-xxx.svg","format":"svg"}
]'

⚠️ 关键规则:ICON / IMAGE 节点必须下载实际资源文件,代码中直接引用文件路径。不要跳过下载自己画 SVG,也不要用占位符,也不要用 Unicode 字符近似替代。

3.3 记录该块的关键样式

读完 JSON 和下载资源后,在继续下一个块之前,用简要注释记录该块的核心信息:

  • 容器布局方式(flex 方向、padding、gap)
  • 关键节点的 customStyle 摘要(字号、颜色、间距等)
  • 该块涉及的资源文件列表

目的是确保每块的 JSON 数据被充分消化,而不是在最终生成时回头翻找。

所有块处理完成后,进入 Step 4 生成代码。


Step 4. 生成代码

阅读 codegen-rules.md

代码生成分两步:先确定结构,再填充样式。

4.1 先写 DOM 结构骨架

基于截图和骨架,先输出纯 DOM 结构(含语义化的 class 名和注释,但不含具体样式值)。这一步只关注:

  • 容器嵌套关系是否合理
  • 需要绝对定位的元素,其定位参考(position: relative 的祖先)是否正确
  • 需要裁切(overflow: hidden)的容器,其子元素是否都在边界内——如有元素需要突出容器边界,该元素必须放在裁切容器外部
  • 重复结构是否使用循环
  • 设计稿的层级与 DOM 层级的映射是否合理(设计稿层级不一定要 1:1 映射到 DOM,合理调整以符合 CSS 布局需要)

4.2 再填充精确样式

结构确认后,从 JSON 的 customStyle 中提取所有精确值填充到代码中:

  • 所有尺寸、颜色、间距直接来自 JSON,不估算
  • ICON / IMAGE 节点直接引用已下载的资源文件路径,不手绘近似 SVG
  • 以截图为参照校验每个区块的视觉效果
  • 输出格式和资源引用方式遵循项目规范(见 codegen-rules.md

Step 5. 视觉验证(可选但强烈推荐)

如果生成的是可直接在浏览器运行的代码(HTML 文件、本地可启动的应用等),使用 Playwright 截图与设计稿截图进行对比验证。最多进行 2 轮修正。

5.1 截图渲染结果

from playwright.sync_api import sync_playwright

with sync_playwright() as p:
    browser = p.chromium.launch(headless=True)
    page = browser.new_page(viewport={"width": 375, "height": 812})
    page.goto('file:///path/to/output.html')
    page.wait_for_load_state('networkidle')
    page.screenshot(path='$WORK_DIR/render-result.png', full_page=True)
    browser.close()

需要 Playwright 环境。如不可用,跳过此步进入完成前回顾。

5.2 逐区域对比

不要泛泛地看"像不像",要逐区域精确对比。 将页面分为 3-5 个视觉区域(与分块计划对应),每个区域单独检查:

  1. 位置:元素在区域内的水平/垂直位置是否与设计稿一致?居中、偏左、还是固定偏移?
  2. 尺寸:元素的宽高比例是否正确?有没有被拉伸或压缩?
  3. 层叠:元素之间的前后遮挡关系是否正确?有没有被裁切、被遮挡?
  4. 间距:元素之间的间距是否合理?太紧或太松?

5.3 聚焦修正

发现差异后,每次只修一个问题,修完立刻重新截图验证。不要一次改多处——同时改多个地方,无法判断哪个改动造成了新问题。

修正优先级:

  1. 结构性问题(元素缺失、层级错误、被裁切) → 修 DOM 结构
  2. 位置问题(偏移、对齐方向错误) → 修定位和布局属性
  3. 细节问题(间距、字号、颜色微调) → 修具体样式值

完成前回顾

生成代码后(如已做视觉验证则在验证通过后),对照截图逐项检查:

  • 截图中的所有视觉元素是否都已实现(包括装饰光晕、阴影等)
  • 骨架中的关键节点是否都有对应代码
  • JSON 是否已完整读完(包括最后的 assets 字段)
  • 所有资源是否已下载,代码中引用的是已下载的文件路径,无手绘近似、无占位符
  • 左右并排结构的对齐是否基于 JSON 的固定尺寸,而非估算
  • 动态数据是否通过接口/Props 传入(非硬编码)
  • 重复结构是否使用数组循环
  • 资源引用方式是否与项目已有代码一致

常见错误

错误 原因 正确做法
资源节点的用途判断错误(如把关闭按钮图标当成装饰图标) 凭节点的 typename 字段猜测用途,未回溯结构树 将资源 nodeId 映射回主 JSON 结构,通过结构位置(父子层级、相邻节点、坐标)确定 UI 角色
位图资源遗漏未下载 只从 assets 数组中查找资源 assets 数组仅包含矢量资源;带 object-fit 属性的 RECTANGLE / IMAGE 节点是位图资源,需从主结构中额外识别并下载
用 Unicode 字符或 HTML 实体代替图标资源 认为简单图标(如 ✕ ⓘ ▶)可以用文字近似 ICON 节点必须使用下载的实际资源文件,文字字符与设计资源在视觉上不等价(大小、粗细、对齐方式均不同)
结构和样式一起写,结构定错后推倒重来 边想结构边写样式,注意力分散导致结构性错误 先写纯 DOM 结构确认合理,再填充样式值
突出元素被 overflow: hidden 裁切 元素放在了圆角裁切容器内部,用负偏移试图突出 突出元素放在裁切容器外部的 wrapper 上绝对定位
资源文件内容被内联为 base64 读取了已下载的文件内容再转为 data URI 直接引用文件路径(<img src="path/to/icon.svg">),不读文件内容
对同一节点多次 curl 分段读取 JSON 直接 pipe 给 head/tail,每次重新请求 > design.json 保存,后续 sed -n 分段读文件
左右对齐结构用 flex:1 拉伸连接线 没有读子节点的 margin-bottom + 固定 height 读 JSON 中每个子节点的 customStyle,用固定尺寸还原
跳过截图,直接看骨架和 JSON 截图当作"可选"步骤 截图必须是第一步
装饰图形(光晕/渐变椭圆)缺失 没有下载无 customStyle 的图形节点 下载 assets 里的所有资源;如骨架有图形节点但不在 assets 里,单独下载确认
SVG 图标手绘近似路径 没下载资源或下载后不用,凭印象自己画 下载资源后在代码中直接引用文件路径(如 <img src="icon.svg">
大 JSON 读到一半就开始写代码 JSON 分段读取时跳过了后半段 必须确认 JSON 完整读取后(含 assets)才进入代码生成
复杂 UI 一口气生成导致细节丢失 上下文窗口无法记住所有节点样式 使用分块路径,逐块消化、逐块生成

参考文档

文档 何时读取
codegen-rules.md 生成代码前必读
design-schema.md 理解 JSON 结构时
api.md 调用 API 或下载资源时

错误处理

api.md 错误格式与错误码。

Installs
14
GitHub Stars
2
First Seen
Jan 26, 2026