name: sketch-inspector description: > 解析 Sketch 图层并导出资源。返回结构化设计数据,包括层级、样式、文本、 颜色,并导出图片资源。用户需要检查 Sketch 设计、提取设计 token、 或根据 Sketch 在任意框架中实现页面时,必须使用此 skill。 metadata: short-description: 解析 Sketch 设计、导出资源、返回结构化数据
Sketch 检查器
将 Sketch 设计转换为结构化数据、图片资源和可实现的页面分块。
使用场景
- 检查已打开的 Sketch 文档或具体图层
- 提取结构、样式、文本、颜色、布局和资源信息
- 根据 Sketch 区域实现 HTML/CSS、React、Vue 或其他页面
前置条件
- Sketch 正在运行,目标文档已打开
- Sketch MCP 已开启:General -> Allow AI tools to interact with open documents
- MCP 服务地址:
http://localhost:31126/mcp - Sketch Run Code 运行在 JavaScriptCore/CocoaScript 环境,不是普通 Node.js
页面实现强制流程
从 Sketch 生成页面时必须严格执行以下流程,这是唯一最快完成任务的途径,缺少任一步都视为失败:
1. 扫描
提取页面或目标容器的浅层轮廓,确认根节点 layerId。
2. 确定路径
imageOutputDir:项目图片目录,优先使用现有images/、assets/images/、public/images/等workTmpDir:临时目录,至少放result.json;大文件拆分时还会放manifest.json、section JSON、section HTML
3. 导出
在 sketch_run_code 中运行导出脚本。
const sketch = require('sketch');
// 参数准备
const layerId = '<目标图层的 layerId>'; // 从步骤 1 扫描获取的目标根节点 ID
const outputDir = '<imageOutputDir 绝对路径>'; // 如: '/Users/edy/project/images'
const outputJsonPath = '<workTmpDir/result.json 绝对路径>'; // 如: '/Users/edy/project/tmp/result.json'
// 执行导出脚本
const exportScript = require('@scripts/export-text-split-assets.js');
const result = exportScript.runExportTextSplitAssets({
layerId: layerId,
outputDir: outputDir,
outputJsonPath: outputJsonPath
});
// 输出结果用于调试
console.log(JSON.stringify(result, null, 2));
返回结果:
- 成功:返回导出统计信息
- 失败:返回错误信息,检查
layerId是否有效、路径是否有写入权限
注意:
- 脚本运行在 Sketch JavaScriptCore 环境,不是普通 Node.js
- 路径必须是绝对路径
- 输出目录必须存在,脚本不会自动创建
4. 布局推断并覆盖 result.json
Shell 运行:
npx tsx @scripts/sketch_layout_ir_inference.ts \
<workTmpDir>/result.json \
<workTmpDir>/result.json
这一步会把导出的原始结构转换成可直接实现的统一布局 JSON,并覆盖原来的 result.json。
输出统一 result.json 结构:
kind:flex|grid|absolute|leafdirection:row|column(仅 flex)gap: 子元素间距padding: 内边距 { top, right, bottom, left }justifyContent: flex 对齐方式alignItems: 交叉轴对齐方式hasAbsoluteChildren: 当flex/grid容器存在直属absolute子节点时为truecss.position: "relative":当flex/grid容器存在直属absolute子节点时显式输出columns/rows: 网格行列数(仅 grid)source: 与当前布局节点对应的实现补充数据,仅保留sourceClass / asset / background / style / decision / backgroundLayers / derivedFrom等非布局字段
5. 布局探测后必须分流
布局推断完成后,不允许凭感觉决定实现方式,必须按统一后的 result.json 实际行数分流:
result.json少于或等于3000行:直接读取整个result.json完成实现,不再拆分result.json多于3000行:必须进入“大文件拆分流程”,禁止直接把整个 JSON 塞给后续实现步骤
行数检查示例:
wc -l <workTmpDir>/result.json
6. 小文件主流程:直接实现
适用条件:result.json 行数 <= 3000
核心规则(MUST FOLLOW):
- 禁止普通布局使用 absolute:只有
kind: "absolute"的节点才允许绝对定位 - 有直属 absolute 子节点时,必须信任
result.json的定位信号:若节点输出了hasAbsoluteChildren: true或css.position: "relative",实现时必须给该父容器设置已定位状态,不能忽略
生成流程:
- 读取完整
result.json - 递归遍历布局树
- 根据
kind生成对应 CSS:flex:display: flex; flex-direction: {direction}; gap: {gap}px; ...grid:display: grid; grid-template-columns: repeat({columns}, 1fr); ...absolute:position: relative;子元素position: absolute;leaf: 无布局,渲染内容即可
- 直接使用当前节点的
source完成文本、图片、背景、样式、决策实现,不再回查旧结构 JSON
7. 大文件主流程:拆分 -> 单 Section 实现 -> 回填汇总
适用条件:result.json 行数 > 3000
7.1 拆分 JSON
Shell 运行:
node @scripts/split-result-json.js \
--inputJsonPath=<workTmpDir>/result.json \
--outputDir=<workTmpDir> \
--assetBasePath=images/ \
--splitStrategy=auto
输出:
<workTmpDir>/manifest.json- 多个 section JSON
- 约定好的
implementationPath、htmlMarker、cssMarker manifest.json.root.layoutIR:页面主布局语义摘要manifest.json.sections[].layoutIR:section 节点自身的布局语义摘要
7.2 单 Section 实现
每个 section 必须只读取自己的 jsonPath,并按 manifest.json 写入自己的 implementationPath。
强制规则:
- 单 section 实现流程见
@references/single-section-workflow.md - section 文件必须是片段:一个
<section>+ 一个<style> - section 内只写内部结构和内部样式,不定义主布局容器的外层 margin
- 非根选择器必须按
className做作用域隔离 - 需要深度检查时再用
@scripts/inspect-single-section.js
7.3 回填汇总
所有 section 实现完成后,必须把每个 section 片段回填到总布局文件,不能手工复制粘贴 marker 内容。
主布局文件必须预先满足:
htmlMarker放在页面结构中需要插入 section 的位置cssMarker必须放在主布局文件的<style>块内部,不能放在其他标签、注释区块外层或正文结构中- 如果 HTML 和 CSS 分文件,
cssMarker必须放在cssLayoutPath指向的 CSS 文件中
Shell 运行:
node @scripts/replace-section-placeholder.js \
--layoutPath=/path/layout.html \
--sectionPath=/path/01-section.html \
--htmlMarker="<!-- 01-section HTML -->" \
--cssMarker="/* 01-section CSS */"
如果 HTML 和 CSS 在不同文件,额外传 --cssLayoutPath。
8. 实现检查清单
实现前确认:
- 完整读取
result.json - 检查每个节点的
kind字段 - 检查
meta.background背景层信息 - 文本、图片、图层关系已检查
- 品牌资产和复杂视觉组已识别
9. 交付
报告客观产物:
- 布局轮廓和目标区域 id
result.json路径和实际行数- 使用的是“小文件直接实现”还是“大文件拆分流程”
- 如走拆分流程:
manifest.json路径、section 数量、回填目标文件路径 - 布局类型统计(flex/grid/absolute/leaf 数量)
- 导出资源清单
- 生成的 HTML/CSS 文件路径
不要输出"已视觉验证"等机器无法判断的结论。
固定脚本
脚本参数和返回结构见 @references/script-api.md。
@scripts/export-text-split-assets.js:导出图片和 JSON。必填layerId、outputDir@scripts/sketch_layout_ir_inference.ts:布局推断并输出统一后的result.json@scripts/split-result-json.js:大文件主流程脚本,生成manifest.json和多个 section JSON@scripts/replace-section-placeholder.js:大文件主流程脚本,把 section 实现回填到总布局文件@scripts/inspect-single-section.js:section 信息不足时做局部深度检查
禁止:自己生成导出脚本、复制脚本源码、重新实现遍历逻辑。
LayoutIR 类型说明
type LayoutKind = 'leaf' | 'flex' | 'grid' | 'absolute'
interface FlexIR {
kind: 'flex'
direction: 'row' | 'column'
gap: number
padding: { top, right, bottom, left }
justifyContent: 'flex-start' | 'center' | 'flex-end' | 'space-between'
alignItems: 'flex-start' | 'center' | 'flex-end' | 'stretch'
children: LayoutIR[]
}
interface GridIR {
kind: 'grid'
columns: number
rows: number
columnGap: number
rowGap: number
padding: { top, right, bottom, left }
children: LayoutIR[]
}
interface AbsoluteIR {
kind: 'absolute'
children: LayoutIR[] // 子元素需要绝对定位
}
interface LeafIR {
kind: 'leaf'
text?: string
css: { width?, height? }
}
资源导出规则
- 图片输出到
imageOutputDir,临时 JSON 放workTmpDir - 图片文件名用 MD5 前 8 位,相同图片复用
asset/exports只保留path、src、x、y、width、height。生成代码引用src,不用path- JSON 删除空值和值为
0的 style 字段 - 默认过滤隐藏图层
- 含真实 Text 的节点必须拆分,不能整体导出为图片
- 普通背景 Rectangle 用代码重建;品牌资产、复杂视觉组优先保真导出
参考索引
@references/export-assets.md:资源导出规则@references/script-api.md:脚本参数和返回结构@references/single-section-workflow.md:单 section 实现流程