关于 penpot-document-handoff
将 Penpot 设计整理成交接材料的技能,可添加背景卡片、编号标记、对应备注和可选提示框。它在原设计旁创建可隐藏的注释层,不修改原设计。
主要功能
- 01在设计旁创建背景卡片
- 02添加编号标记和对应备注
- 03为临时状态添加可选提示框
- 04复用注释组件和令牌
- 05将注释分组以便一键隐藏
适用场景
- 01为审阅者记录设计背景和业务规则
- 02将界面区域关联到观察与建议
- 03用提示框说明临时界面状态
MCP 相关
使用 Penpot MCP 工具检查设计和注释组件、创建独立的注释层,并导出图像供审阅。原设计保持不变。
安装
复制下面的命令,在终端中运行。
npx skills add https:/ / github.com/ penpot/ penpot-ai-kit --skill penpot-document-handoff安装后在 Claude Code 中输入/penpot-document-handoff确认已加载。
包含的文件
除 SKILL.md 外,安装时一起下载的参考资料和脚本。
references/01-annotation-anatomy.md02-handoff-brief.md03-layout-placement.md04-component-and-tokens.md05-anti-rationalization.md06-error-recovery.mdscripts/addTooltipCallout.jsbuildContextCard.jsfinalizeHandoff.jsplacePinAndNote.jssetupAnnotationKit.js详细介绍
penpot-document-handoff — 设计 → 标注交接
1. 标题 + 工作原理
penpot-document-handoff 将已完成(或正在进行)的设计转化为一份自解释的交接文档:
左侧是上下文卡片(“我们可以如何实现”目标、业务规则、链接、设计师、状态、希望/不希望收到的反馈),UI 区域上有编号图钉,右侧是对应的观察/建议便笺卡片,还可以为临时状态添加工具提示——所有标注都放在一个可隐藏的组中,让审阅者只需单击一次即可切回干净的设计。如果已有标注组件工具包和 annotation.* 令牌,则会复用;若没有,则会提出一个精简方案(需人工批准)。所有修改都通过 execute_code 执行;使用 export_shape 进行视觉验证;使用 penpotUtils.shapeStructure 读取结构(完整工具集:shared/penpot-mcp-tool-reference.md)。它会先查找目标设计以及任何现有的标注组件工具包和令牌,然后逐步构建——每次调用添加一个标注标注层,并严格将其作为同级图层添加,绝不修改设计本身。
2. 最重要的一条规则
**在设计旁边标注,绝不覆盖其上——每次调用添加一个标注。**被记录的设计只读:添加一个独立、可隐藏的标注层放在其旁边,绝不移动、重新设置样式或重组原设计中的任何形状。先构建上下文卡片,然后逐个添加图钉和便笺,并在过程中设置检查点。在一次 execute_code 调用中生成整套标注是失败模式。
3. Penpot MCP 工具参考
完整工具集:shared/penpot-mcp-tool-reference.md。此技能主要使用以下调用:
penpotUtils.shapeStructure / findShape / findShapes(查找设计和工具包组件);
penpot.library.local.components + comp.instance()(复用标注工具包);penpot.createBoard()
/ addFlexLayout()(缺少工具包时构建);penpot.group()(可隐藏的包装组——使用
penpot_api_info 验证);shape.applyToken(绑定强调色/表面/字体);在每个检查点调用 export_shape('selection'|<id>)。
4. 插件 API 要点
注意事项编号对应 shared/plugin-api-gotchas.md。
- 设计是只读输入。使用
shapeStructure读取;根据子项的bounds(绝对 x/y/宽度/高度)确定图钉锚点。绝不要对其调用resize/重新设为父项/detach/remove。 - 注释卡片是使用 flex 的画板(
column-reverse,与参考系统一致);通过追加顺序 + 间距 + 内边距组合,绝不要在卡片内使用绝对 x/y。 - 图钉和上下文卡片位于页面的绝对位置(不属于设计的布局)——直接设置
x/y;若将其设为布局画板的子项,则设置layoutChild.absolute = true(#14:绝对定位的子项使用页面坐标,且画板会在边缘裁剪内容)。 - #3 文本自动调整大小——任何
resize()(会强制设为fixed)之后,都将growType设为auto-width/auto-height;读取textBounds前等待约 100 ms。 - #2 异步应用令牌——在一次调用中应用,并在稍后的调用中检查
resolvedValue。 - #11 每个新建画板都会带有不透明的白色填充——这是本技能的关键失败模式。
createBoard()默认设置fills = [{ fillColor: "#FFFFFF", fillOpacity: 1 }]。若保留此设置,结构性包装画板的方形白色边角会从其包裹的圆角卡片后面露出;而任何保留纯白色的画板都不符合设计系统(绝不对其应用主题)。填充策略:备注/上下文卡片和工具提示是真正的表面 → 将其背景绑定到color.annotation.surface(绝不使用纯色值);内部区块画板和包装画板属于结构性元素 → 通过board.fills = []清除填充。 - #13b 精确匹配字体——使用
penpot.fonts.all.find(f => f.name === "Work Sans") || null并添加空值检查;findByName会进行子字符串搜索。若字体不存在,则保留默认字体并报告font-fallback。 - 隐藏用分组:收集每个注释形状,并用
group()将其编入一个命名分组;隐藏时设置group.hidden = true。依赖group()/分组签名前,先通过penpot_api_info验证。
5. 令牌感知简报约定
修改前先复述请求。以资深设计系统 / 交接专家的身份行事,绝不在作品上覆盖注释,也绝不硬编码注释调色板。
- 上下文——产品、受众、正在说明的功能/流程、目标读者(开发者?PM?设计评审?)。
- 目标——需要说明的单个设计(画板/框架或选区),以及交接内容必须明确说明的事项。
- 输入——设计画板 ID;交接简报内容(US 编号、标题、“How might we”目标、上下文/业务规则、链接、设计师、状态、平台、希望获得/不希望获得的反馈);需要标注图钉的 UI 区域列表及其观察说明(可选建议);需要工具提示说明的临时状态。
- 约束——不得修改设计;若有注释套件则重复使用(否则提出一个);将强调色/表面/字体绑定到令牌(若缺少则提出
annotation.*令牌,由人工审批);图钉按连续编号排列,并与备注一一对应;所有内容都位于可隐藏分组内。 - 验收标准——设计逐字节保持不变;每个图钉恰好对应一条备注,反之亦然;编号从 1 开始连续排列;所有注释文本均绑定到注释字体令牌;强调色和表面均绑定到令牌;整个图层可通过单个分组开关隐藏/显示;保持三列阅读顺序(上下文 | 设计 | 备注)。
6. 强制工作流
**视觉自检(强制):**在每个展示视觉成果的 ✋ 检查点之前,运行
shared/visual-self-review.md中的导出 → 查看 → 修复循环——导出刚刚构建的单元,对照清单亲自检查图像,修复可见缺陷(最多 2 轮),并展示同一份导出,同时指出仍存在的缺陷。
**阶段 0 — 探索(只读)。运行 high_level_overview;确定目标设计(penpot.selection 或指定的画板),并将其 ID 复制到 storage.dh;读取其结构(采用 scripts/locateDesign 模式,深度为 2–3),枚举可添加标注的区域;盘点标注工具包和令牌(使用 dryRun 运行 scripts/setupAnnotationKit.js)。✋ 检查点:**确认设计,以及是否已有工具包或需要创建。
**阶段 1 — 交接简报。**收集/确认上下文卡片内容和标注列表(区域 → 观察结果 → 可选建议)。使用 references/02-handoff-brief.md / prompts/handoff-brief.md。
**✋ 检查点:**开始绘制前,先批准简报和标注列表。
**阶段 2 — 准备标注工具包。如果已有工具包组件和 annotation.* 令牌,则复用它们。如果没有,提议最精简的工具包(Critique Card、Chip Note、Pointer S/L、Tooltip)和令牌(color.annotation.accent、color.annotation.surface、color.annotation.on-accent、color.annotation.body、font.annotation.title|body|label),具体参见 references/04-component-and-tokens.md;仅在获批后创建(运行 scripts/setupAnnotationKit.js)。✋ 检查点:**批准工具包,以及令牌名称/值/层级。
阶段 3 — 上下文卡片。构建/实例化 Critique Card,根据简报填写内容,将其放在设计的左侧(scripts/buildContextCard.js)。**✋ 检查点:**对卡片运行 export_shape。
阶段 4 — 标注和备注(每次调用一个)。针对每个区域:在设计中放置一个锚定到该区域的编号 Pointer/L 标注,并在右侧栏放置编号相同的 Chip Note(scripts/placePinAndNote.js)。可选地添加 Tooltip,说明临时状态(scripts/addTooltipCallout.js)。每次 execute_code 调用只能添加一个标注。 **✋ 检查点:**每次(或每个小批次)完成后运行 export_shape。
**阶段 5 — 收尾与审计。**将所有标注形状归入一个名为 Hide this to quit notes 的可隐藏分组;运行自检(scripts/finalizeHandoff.js):设计未被修改、标注与备注一一对应、编号连续、令牌已绑定、顺序符合三栏布局。violations 不为空即表示未通过检查——先修复再报告完成。
7. 关键规则
- **绝不修改设计。**不得更改任何原有形状的几何、填充、名称或结构。该技能只会添加同级标注层。若设计的形状集合或边界发生变化,第 5 阶段审计将判定本次运行失败。
- **每次
execute_code调用只能添加一个标注。**先添加上下文卡片,再逐个添加标注和备注。切勿一次性添加整个图层。 - **标注与备注一一对应,编号连续。**每个 Pointer 标注都必须有且只有一个编号相同的 Chip Note;编号从 1 到 N,不得缺号;画布上的标注(L)与备注标题中的标注(S)编号必须相同。
- **复用工具包;提议令牌,绝不硬编码。**实例化现有标注组件;如果缺少工具包/令牌,则先提议并在审核通过后创建——绝不直接使用
#1A88E0/#E4F3FF填充。 - **三栏布局。**上下文卡片置左,设计置中(不作修改),备注卡片在右侧纵向排列;标注覆盖在其指向的区域上。
- **每张卡片内部都使用 Flex。**卡片/分区应为 Flex Board(像参考所示使用
column-reverse),而非绝对定位的文本或普通 Group。 - **所有内容均可通过一个分组隐藏。**所有标注形状都必须归入一个命名分组,让审核人员只需单击一次即可切换到干净的设计。
- **默认模式 = 审核。**创建几何图形后,每个阶段都设有检查点;创建工具包/令牌属于不会自动修复的更改,必须经批准。
8. 领域架构
标注层在未修改的设计周围分为三列:
[ Critique Card ] [ the design (read-only) ] [ Chip Note #1 ]
#US · title ┌─────────┐ number+TITLE
State/Copy/Platform │ ① ② ③ │ ← Pointer/L pins Observation
status pill │ UI… │ on the regions Recommendation?
HMW goal └─────────┘ [ Chip Note #2 ] …
links · designers (+ Tooltip/Top|Bottom for
context transient states)
feedback wanted
feedback NOT wanted
卡片、图钉和工具提示都放在同一个组中:Hide this to quit notes。
组件套件和令牌分类:references/01-annotation-anatomy.md、references/04-component-and-tokens.md。
9. 模式与策略
默认采用审查模式(shared/modes-and-policies.md)。创建几何图形、组件或令牌时,始终需要设置检查点。本技能可自动应用的安全集项目:添加文档元数据(plugin-data 标签),以及重命名刚创建的自动命名标注层。绝不自动修复:创建套件组件、创建 annotation.* 令牌,以及(始终)对所记录设计所做的任何更改。填充策略:备注/上下文卡片是真正的表面 → 将其背景绑定到 color.annotation.surface;内部区块板属于结构性元素 → fills = []。
10. 状态管理
在 RUN_ID 下记录账本(shared/state-management.md),存放于 storage.dh,并在文件中留下导航标记:
phase、designBoardId、kit:{critiqueCardId,chipNoteId,pointerSId,pointerLId,tooltipId,created}、
tokens:{accent,surface,...}、contextCardId、notesColumnX、groupId、
pins:[{n,regionId,pinId,noteId}]、pinCounter。恢复时:重新读取账本,通过结构读取(组和图钉)重新核实实际状态,并从 pinCounter 继续。
11. 用户检查点
| 阶段之后 | 展示的内容 | 需要确认的事项 |
|---|---|---|
| 0 发现 | 设计摘要 + 可添加图钉的区域 + 套件/令牌是否存在 | 确认目标和套件计划? |
| 1 简报 | 上下文卡片内容 + 编号图钉列表 | 批准简报和图钉? |
| 2 套件 | 拟议组件 + 令牌名称/值/层级(仅在创建时) | 批准套件和令牌? |
| 3 上下文卡片 | 卡片的 export_shape | 批准内容/位置? |
| 每个图钉+备注 | 区域和备注的 export_shape | 批准/调整? |
| 5 收尾与审计 | 可隐藏的组 + 审计结果 | 批准交接/继续迭代? |
12. 命名约定
shared/naming-conventions.md。组件采用 PascalCase(Critique Card、Chip Note、Pointer、
Tooltip;复用时保留参考系统中的名称)。令牌在 annotation 集下采用点号命名(color.annotation.accent、font.annotation.label)。图层采用 kebab-case/语义化命名(context-card、note-card、pin、annotations);可隐藏的组保留易识别的名称
Hide this to quit notes。图钉标签使用整数索引。
13. 反合理化表
| 大模型给出的借口 | 错误原因 | 可立即停止流程的确定性应对措施 |
|---|---|---|
| “我只要把备注文本放在设计上方/重新给某个图层上色来突出它就行。” | 这会修改交付内容;交接注释必须可移除且不具破坏性。 | 停止。将同级注释形状添加到备注列,或添加 Pointer 图钉叠加层;绝不能编辑原始形状。如果设计发生变化,第 5 阶段的审查将判定失败。 |
“我会用一次 execute_code 创建所有图钉和备注,省得多次调用。” | 一次性输出无法审查,还会导致图钉与备注的编号不同步。 | 每次调用只添加一条注释;使用 export_shape 设置检查点;每次都递增 storage.dh.pinCounter。 |
“强调蓝色只是装饰——直接写死 #1A88E0 就行。” | 不符合系统规范的值无法通过治理审核,也无法随主题或品牌重塑而变化。 | 绑定到 color.annotation.accent;如果该项不存在,则提交它的名称、值和层级以供审批。 |
| “这条备注其实不需要图钉——它是通用信息。” | 孤立备注会破坏审查者依赖的编号→区域阅读模式。 | 每个 Chip Note 都要在具体区域放置一个 Pointer 图钉;如果确实是全局信息,则应放在上下文卡片中,而不是备注里。 |
| “纯文本块比实例化 Chip Note 组件快。” | 原始文本会偏离系统规范,且无法随工具包一起更改样式。 | 实例化工具包组件;如果工具包缺失,则创建一次(需审核),然后重复使用。 |
| “我之后再给备注重新编号;现在顺序无关紧要。” | 编号缺失或重复会悄无声息地破坏交接内容。 | 每个步骤都保持编号连续且相互匹配;审查会拒绝缺号或重号。 |
| “我会跳过可隐藏组;图层已经够整洁了。” | 没有统一开关,审查者就无法恢复干净的设计。 | 报告完成前,将所有注释形状放入单个 Hide this to quit notes 组。 |
14. 辅助代码片段
// Phase 0 — lock the target design + enumerate pinnable regions (READ-ONLY)
const design = penpot.selection[0] || penpotUtils.findShape(s => s.name === "REPLACE-ME-board");
if (!design) return { error: "Select the design board to document, or pass its name." };
storage.dh = Object.assign(storage.dh || {}, { designBoardId: design.id });
const regions = (design.children || []).map(c => ({
id: c.id, name: c.name, type: c.type,
x: Math.round(c.x), y: Math.round(c.y), w: Math.round(c.width), h: Math.round(c.height)
}));
return { design: { id: design.id, name: design.name, x: Math.round(design.x), y: Math.round(design.y),
w: Math.round(design.width), h: Math.round(design.height) }, regionCount: regions.length, regions };
// Reference palette/typography of the annotation system (verified from the example file).
// Use these as the VALUES when proposing annotation.* tokens — do NOT paint them raw on shapes.
return {
color: { accent: "#1A88E0", surface: "#E4F3FF", onAccent: "#FFFFFF", body: "#000000" },
type: { family: "Work Sans",
label: { size: 12, weight: 500, case: "uppercase", fill: "accent" },
body: { size: 14, weight: 400, fill: "body" },
title: { size: 24, weight: 400, fill: "body" } },
card: { bg: "surface", padding: [24,12,24,12], flexDir: "column-reverse", sectionGap: 24, labelGap: 4 },
pin: { L: 40, S: 24, radius: 9999, bg: "accent", number: "onAccent" }
};
15. 参考资源
penpot_api_info('Board')、penpot_api_info('LibraryComponent')、penpot_api_info('Text')、penpot_api_info('Context','group')— 包装前验证分组签名。shared/penpot-mcp-tool-reference.md(工具接口)、shared/plugin-api-gotchas.md(#11 填充 策略;异步令牌;resize→growType)、shared/tokens-schema.json(令牌type的拼写)。
16. 支持文件
references/(渐进式披露的深入资料)
| 文件 | 加载时机 | 内容 |
|---|---|---|
references/01-annotation-anatomy.md | 阶段 2–4 | 逆向分析所得的系统:Critique Card 分区、Chip Note 结构、Pointer S/L、Tooltip、调色板/字体、可隐藏组。 |
references/02-handoff-brief.md | 阶段 1 | 如何收集/组织上下文卡片内容和图钉列表。 |
references/03-layout-placement.md | 阶段 3–4 | 三列几何布局、图钉锚定计算、备注堆叠、间距节奏。 |
references/04-component-and-tokens.md | 阶段 2 | 查找或创建注释组件工具包及 annotation.* 令牌提案。 |
references/05-anti-rationalization.md | 任意阶段 | 扩展版失败模式目录及应对措施。 |
references/06-error-recovery.md | 失败时 | 针对工具包缺失、编号错误、意外修改设计、组/取消组合问题的恢复方法。 |
scripts/(粘贴到 execute_code 的模板)
| 文件 | 阶段 | 用途 |
|---|---|---|
scripts/setupAnnotationKit.js | 0/2 | 清点工具包和令牌;在非 dryRun 模式下,创建最简工具包并提出令牌建议。 |
scripts/buildContextCard.js | 3 | 构建/实例化 Critique Card,并根据简报填写内容。 |
scripts/placePinAndNote.js | 4 | 在某个区域添加一个编号图钉,并添加与之匹配的 Chip Note。 |
scripts/addTooltipCallout.js | 4 | 为瞬态/悬停状态添加可选的 Tooltip 标注。 |
scripts/finalizeHandoff.js | 5 | 将标注封装在可隐藏组中,并运行一致性/未触碰项/令牌审计。 |
规范路径。 在原生安装中,shared/… 和 policies/… 会解析到此捆绑包内(由安装程序随附);在 Claude Code 插件安装中,它们位于插件根目录,即 ${CLAUDE_PLUGIN_ROOT}/shared/…,从此文件向上两级。