关于 penpot-build-deck
penpot-build-deck 是一项技能,可根据简报在 Penpot 中创建可编辑的幻灯片设计。它按阶段逐页构建、检查导出的幻灯片,并将画板连成可播放的流程。
主要功能
- 01先规划完整幻灯片大纲
- 02创建可编辑的 1920×1080 幻灯片画板
- 03应用演示文稿令牌与字体
- 04通过导出内容逐页检查
- 05检查布局多样性与演示文稿质量
- 06将幻灯片连接为可播放流程
适用场景
- 01根据简报制作可编辑演示文稿
- 02分批构建并审阅幻灯片
- 03准备在 Penpot View mode 播放并导出 PDF
MCP 相关
该技能使用 Penpot MCP 工具创建和编辑页面、画板、布局、文本、令牌、媒体及流程,并参考 Penpot MCP 工具接口进行实现与检查。
安装
复制下面的命令,在终端中运行。
npx skills add https:/ / github.com/ penpot/ penpot-ai-kit --skill penpot-build-deck安装后在 Claude Code 中输入/penpot-build-deck确认已加载。
包含的文件
除 SKILL.md 外,安装时一起下载的参考资料和脚本。
references/01-deck-brief-analysis.md02-deck-styles.md03-slide-archetypes.md04-typography-and-grid.md05-visuals-and-effects.md06-flow-and-playback.md07-critique-framework.md08-anti-rationalization.md09-error-recovery.mdscripts/applyDeckEffects.jsauditDeckQuality.jsbuildSlide.jscreateDeckPage.jssetupDeckSystem.jswireDeckFlow.js详细介绍
penpot-build-deck — 将简报转化为可播放的幻灯片演示文稿
1. 标题 + 工作原理
penpot-build-deck 可将简报转化为存放在 Penpot 中的真实、可编辑设计演示文稿:
每张幻灯片对应专属页面上的一个 1920×1080 画板,通过 deck.* 令牌集进行令牌化,并连接
到一个 流程,让演示文稿可在 Penpot 的查看模式中播放(←/→,Shift+F 全屏),还可导出为
PDF。所有更改都通过 execute_code 执行;使用 export_shape 进行视觉验证(逐张幻灯片
验证,绝不导出整个页面);使用 penpotUtils.shapeStructure 读取结构(完整工具参考:
shared/penpot-mcp-tool-reference.md)。Penpot 没有“幻灯片模式”——本技能就是演示文稿
工具链:大纲 → 演示文稿系统 → 样式冻结 → 分批制作幻灯片 → 流程 + 质量门槛。
2. 最重要的一条规则
先规划完整大纲,然后每次调用只制作一张幻灯片。 绝不能在一次 execute_code 中生成整套
演示文稿。第 1–3 张是样式冻结:之后的所有内容都沿用其中的设计决策。其余部分分批制作,
每批 3–5 张;在检查点之前导出并查看每张幻灯片,并避免出现 AI 幻灯片的典型问题(标题下方
的强调线、装饰条、正文居中、纯文字幻灯片、连续两张使用相同布局)。
3. Penpot MCP 工具参考
完整工具参考:shared/penpot-mcp-tool-reference.md。领域调用:penpot.createPage() /
openPage()(两次调用的页面协议);createBoard() + resize(1920, 1080);addFlexLayout() /
addGridLayout();createText() + penpot.fonts.all(精确名称)+ font.applyToText();
applyToken;penpot.uploadMediaUrl(name, url);page.createFlow(name, board);
shape.addInteraction("click", { type: "navigate-to", destination, animation });
board.waitForLayoutUpdate();export_shape(slideId)。
4. 插件 API 要点
注意事项编号参见 shared/plugin-api-gotchas.md。
- #15 页面定位——本技能的关键故障模式。 演示文稿位于独立页面上,而在错误页面上创建的
画板无法移动(跨页面的
appendChild会静默失效)。scripts/createDeckPage.js会执行 两次调用的协议:调用 A 创建并打开页面,调用 B 在执行任何createBoard()之前断言penpot.currentPage.id是否匹配。如果 B 失败,请停止操作并让用户在 UI 中打开该页面——绝不要 在错误页面上继续构建。 - #11 填充策略。 幻灯片画板就是唯一的表面:设置
fills = [],然后绑定deck.bg.<tone>。 每个内部容器(safe-area、列、行、纯分组用的卡片)都保持fills = []; 只有真正的卡片/面板才绑定deck.surface.*。 - #13b 精确字体。
penpot.fonts.all.find(f => f.name === "Inter")——findByName会匹配 子字符串,可能返回“Inter Tight”或“Roboto Mono”。在applyToText之后重新断言fontSize/lineHeight。 - #14 边缘装饰是按页面坐标定位的绝对定位子元素;画板会在边缘裁剪它们——这就是出血效果。
- 每张幻灯片之后都执行 #16
clearFlip(参见shared/visual-effects.md§7);镜像在shapeStructure中不可见,但在导出结果中一目了然。 - #17 在同一次调用中读取几何信息之前,先执行
await board.waitForLayoutUpdate()。 - #18 图像填充是异步且可能失败的——默认使用占位符;仅为用户提供的 URL 上传图片, 并在下一次调用中验证。
- #2 令牌异步应用——在构建调用中绑定,在审计中验证
shape.tokens。 - 对不熟悉的签名,先使用
penpot_api_info验证(Page.createFlow、Shape.addInteraction、Board.backgroundBlur、GridLayout)。
5. 兼顾 Token 的简报约定
- 背景 — 受众、场合、时长、场地/屏幕、语言。
- 目标 — 受众离开时必须记住的一个信息,以及请求/行动号召(CTA)。
- 输入 — 大纲(每张幻灯片一行)、事实和数据及其来源、注明出处的引言、图片 URL(或“占位符”)、可复用的现有 Token/组件/字体。
- 约束 — 不得编造数字;字体必须存在于
penpot.fonts.all中;每张幻灯片都必须有视觉元素;禁止:标题下方的强调线、装饰性横条/条纹、居中的正文、默认蓝色、奶油色背景、纯文字幻灯片;仅使用deck.*Token(渐变/阴影/玻璃效果作为台账记录的字面值);开启严格反敷衍模式时,方向步骤拒绝的键(shared/anti-slop.md§1、penpot-anti-slop中的 deck 相关说明references/04-deck-tells.md)。 - 验收标准 — 每张幻灯片都是一块 1920×1080 的画板,命名为
NN-archetype-slug;每张幻灯片至少有 1 个视觉元素;不能连续两张使用相同的版式类型,且任何一种版式类型不得超过整套幻灯片的 40%;字号下限为 20 px,正文不小于 28 px;对比度至少为 3:1(文本 ≥ 24 px 或粗体 ≥ 18.67 px)/低于该字号时至少为 4.5:1;Deck流程需连线为点击 → 下一张;七个维度的 deck 质量评分均须 ≥ 3,否则须指出薄弱维度;开启严格反敷衍模式时,整套幻灯片页面的敷衍评分须 ≤ 35。
请以一位资深演示文稿设计师的身份行事,带来显著的规模化影响,充分利用整个画布,让每张幻灯片的视觉锚点各不相同,并且绝不交付纯文字幻灯片。
6. 强制工作流
视觉自检(强制): 每次 ✋ 检查点之前,对上次检查点以来构建的每张幻灯片运行
shared/visual-self-review.md中的导出 → 查看 → 修复循环(每个检查点最多进行 2 轮自我修复),并展示这些导出,同时指出所有遗留缺陷。
阶段 0 — 探索 + 大纲(只读)。 high_level_overview;penpotUtils.tokenOverview();
penpot.fonts.all.map(f => f.name);penpotUtils.getPages()。分析简报
(references/01-deck-brief-analysis.md):幻灯片数量上限、核心信息、大纲表格
n | archetype | title | key content | visual | tone、情绪变化弧线、主题元素。选择一种幻灯片风格
(references/02-deck-styles.md),并运行多样性预检(references/03-slide-archetypes.md)。
反俗套选项: 读取已存储的偏好(penpot-anti-slop → scripts/antiSlopPrefs.js);如果尚未设置,且简报未说明,则用用户的语言提出一次 shared/anti-slop.md §0 中的问题,并存储答案。若选择 on,则在选择幻灯片风格之前运行方向步骤(penpot-anti-slop
references/02-direction-playbook.md + 04-deck-tells.md),并将拒绝项添加到约束中。
✋ 检查点:批准大纲 + 风格 + 情绪变化弧线 + 幻灯片数量(严格模式下还包括方向区块)。
阶段 1 — 幻灯片系统。 运行 scripts/createDeckPage.js(先设 PHASE=create,下次调用时再设 PHASE=verify)。运行 scripts/setupDeckSystem.js:令牌集 deck(存在时映射到现有品牌令牌)、字体解析、可选的母版组件。在此提出新令牌,绝不可暗中臆造。✋ 检查点:批准令牌 + 字体。
阶段 2 — 风格冻结。 使用 scripts/buildSlide.js 构建 01-cover-…、02-agenda-… 和第一张内容幻灯片(背景效果使用 scripts/applyDeckEffects.js),每次调用构建一张幻灯片;逐张导出并自检。✋ 风格冻结检查点——之后任何风格变更都将重新开启此检查点。
阶段 3..N — 分批构建。 每批 3–5 张幻灯片,每次调用构建一张;每次调用都使用 clearFlip。每批完成后,导出每张幻灯片,并根据上一张幻灯片检查多样性规则。图片 URL 会在 applyDeckEffects.js 中上传,并在后续调用中验证。✋ 每批设置一个检查点。
阶段 N+1 — 连线、质量门禁、评审。 运行 scripts/wireDeckFlow.js(顺序、Deck 流程、点击 → 下一张、可选自动前进、章节流程)。运行 scripts/auditDeckQuality.js——门禁结果不是 pass 时不得标记为“完成”。然后进行评分评审(references/07-critique-framework.md):七个维度 + 单调性检查;任何维度低于 3 → 针对性修订(最多 2 轮)→ 按 shared/report-schemas/deck-quality-report.schema.json 输出 Markdown + JSON,并同步到台账。开启严格模式时:在幻灯片页面上运行 penpot-anti-slop 诊断(MODE = "deck"),并纳入反俗套评分。提供 PDF 导出和分享链接步骤(references/06-flow-and-playback.md)。✋ 最终检查点。
7. 关键规则
- 每次
execute_code调用只创建一张幻灯片。 大纲整体规划,画布则一次构建一张幻灯片。 - 每张幻灯片都是一个 1920×1080 Board,命名为
NN-archetype-slug,showInViewMode = true、clipContent = true,并放置在演示文稿页面的缩略图网格上。 - 填充策略(#11):幻灯片 Board 绑定
deck.bg.<tone>;分组容器保持透明。 - 优先使用令牌:颜色、字号/字体系列、间距、圆角使用
deck.*。渐变、玻璃填充和阴影无法绑定令牌——每一项都必须在账本的exceptions中记录,并注明其派生令牌。 - 每张幻灯片至少包含 1 个视觉元素(形状、图像/占位符、≥ 140 px 的统计数字、图表占位符、组件实例)。纯文本幻灯片无法通过检查。
- 多样性规则:相邻幻灯片至少在原型 / 锚点 / 色调中的一项上有所不同;不得连续使用相同原型;任何一种原型不得超过整套幻灯片的 40 %。
- 字号下限为 20 px;正文 ≥ 28 px;标题为 72–96 px(
references/04-typography-and-grid.md);字体系列 ≤ 2 种,字重 ≤ 3 种;句首字母大写;正文左对齐。 - 内容准确可信:数字只能来自简报,且每个数字都要标注来源行;引文须注明出处;不得使用占位文本或“Item 1”。
- 图像:除非用户提供 URL,否则使用带标签的占位符;下一次调用时验证上传结果;发生失败时须报告,绝不静默替换。
- 避免明显套路:标题下的强调线、装饰性条带、居中正文、默认蓝色、奶油色背景、白底紫色渐变,以及连续使用相同布局。
- 每张幻灯片后调用
clearFlip(slide);读取几何信息前先执行await waitForLayoutUpdate()。 - 流程也是“完成”的一部分:未运行
wireDeckFlow.js,不得进行最终检查点。 - 检查点遵循 §11——“看起来不错”仅表示批准刚展示的那一批。
8. 领域架构
页面 Deck — <title> → 采用 4 列缩略图网格排列的幻灯片 Board(x = (i % 4)·2080,y = ⌊i/4⌋·1240)
→ 每张幻灯片:根 flex column,内边距绑定到 deck.space.margin(96)→ safe-area
容器(按原型采用行 / 列 / addGridLayout,在 12 列网格上跨列:4 = 544、
6 = 840、8 = 1136)→ 文本(h1、eyebrow、p、stat、caption)、形状、img-placeholder
矩形、组件实例 → 每张幻灯片上的隐藏 notes 文本图层(演讲者备注约定)→
从幻灯片 01 开始的 Deck 流程 + 可选的 Section: <name> 流程。原型目录和各原型的制作方法:references/03-slide-archetypes.md。
9. 模式与策略
默认使用 review。此处的安全操作集:将幻灯片 Board 重命名为符合 NN-archetype-slug 约定的名称。
其他所有操作(几何、令牌、效果、流程连线、上传)均须应用后审核
(shared/modes-and-policies.md)。
10. 状态管理
账本位于 RUN_ID 下(deck-<date>-<slug>):phase、deckPageId、deckStyle、tonalArc、motif、
outline[]、slides:[{ n, id, name, archetype, done }]、styleFrozen、flowName、exceptions[]、
capabilities(记录 waitForLayoutUpdate、uploadMediaUrl、addGridLayout、backgroundBlur、
播放顺序方向的判定结果)、deckQuality、antiSlop(严格模式开启时的 pref、direction、reports[];
opt-in 本身是文件级插件数据 penpot-ai → prefs.antiSlop)。storage.deck 会镜像会话所用的 ID。恢复时:重新读取
账本,重新运行 createDeckPage.js PHASE=verify,按名称(^\d{2}-)重新推导幻灯片列表,
从第一张 done: false 的幻灯片继续(shared/state-management.md)。
11. 用户检查点
| 阶段之后 | 产物 | 询问 |
|---|---|---|
| 0(未设置 pref) | 反套路风格选择题(shared/anti-slop.md §0) | 避免泛泛的 AI 风格? |
| 0 | 大纲表格 + 风格 + 情绪曲线 + 主题元素 + 幻灯片数量(严格模式下还需方向说明块) | 批准方向? |
| 1 | 令牌列表(别名 / 新建 / 字面值)+ 找到的字体 | 批准演示文稿系统? |
| 2(冻结风格) | 幻灯片 01–03 的导出文件 | 冻结此风格? |
| 每个批次 | 此批次幻灯片的导出文件 + 多样性检查 | 批准此批次? |
| N+1 | 流程摘要 + 检查结果 + 评分评审(7 个维度 + 单调性) | 批准 / 迭代?提供 PDF / 分享步骤。 |
12. 命名约定
shared/naming-conventions.md 加上:画板 NN-archetype-slug(01-cover-launch、
07-big-number-retention);图层采用语义名称(h1、h2、eyebrow、p、stat、caption、
img-placeholder、card、safe-area、notes);令牌采用 deck.*(deck.bg.dark、deck.text.on-dark、
deck.accent、deck.font.size.title、deck.space.margin);流程为 Deck、Section: <name>;
RUN_ID 为 deck-2026-09-10-a。
13. 反合理化对照表
| 借口 | 错在哪里 | 应对措施(停止) |
|---|---|---|
| “我一次调用就构建全部 12 张幻灯片——代码都一样。” | 一次性生成的演示文稿无法审查,而且每张幻灯片都会变得一模一样。 | 每次调用制作一张幻灯片;每批 3–5 张;在每个检查点前先导出并查看。 |
| “标题下方加一条强调线看起来很精致。” | 这正是 AI 生成幻灯片的典型标志。 | 标题下方不要加线条或横条——通过大小和字重建立层级。 |
| “所有内容页都用相同布局才算统一。” | 风格才是统一性;布局重复才是单调。 | 多样性规则:更换原型、锚点或语气;检查机制会统计连续重复。 |
| “一个看起来合理的数据能让观点更有说服力。” | 这是捏造证据(shared/design-quality.md §6)。 | 数字只能来自需求简报,并附上来源说明;否则使用带标签的占位符。 |
| “这张幻灯片只放文字也没问题。” | 纯文字幻灯片会显得像是在阅读,而不是演示。 | 添加该原型必需的视觉元素,或更换原型。 |
| “我会跳过流程;用户可以自己点击浏览画板。” | 没有流程就没有演示文稿,只有画板。 | 标记为“完成”前必须运行 wireDeckFlow.js。 |
| “我去找个肯定存在的图库图片 URL。” | 猜测的 URL 属于捏造内容,而且上传失败时不会显示提示。 | 除非用户提供了 URL,否则使用占位符。 |
| “在我的显示器上,24 px 的正文读起来没问题。” | 在 1920×1080 分辨率下,从房间后排看会难以辨认。 | 正文 ≥ 28 px,最低不得低于 20 px;检查机制会强制执行。 |
| “默认的白色画板适合浅色幻灯片。” | 未绑定的字面值永远不会切换,且不符合系统规范。 | fills = [],然后绑定 deck.bg.light。 |
| “全部居中最稳妥。” | 居中是不做选择的对齐方式;内容会挤在一起。 | 使用整个画布,保持 70/30 的非对称构图,并在每张幻灯片上更换锚点;仅封面、引言和结尾页可居中。 |
| “页面切换成功了,我开始创建画板吧。” | openPage 是异步的;画板会落在旧页面上,而且无法移动。 | 必须先让 createDeckPage.js 的 PHASE=verify 返回 ok: true。 |
14. 辅助代码片段
// Slide frame — the surface + bound margin (one slide per call; see scripts/buildSlide.js)
const slide = penpot.createBoard();
slide.name = "05-big-number-retention";
slide.resize(1920, 1080);
slide.clipContent = true; slide.showInViewMode = true;
const flex = slide.addFlexLayout();
flex.dir = "column"; flex.horizontalSizing = "fix"; flex.verticalSizing = "fix";
slide.fills = []; // drop Penpot's default opaque white
const bg = penpotUtils.findTokenByName("deck.bg.dark");
if (bg) slide.applyToken(bg, ["fill"]);
const margin = penpotUtils.findTokenByName("deck.space.margin");
for (const side of ["paddingTop", "paddingBottom", "paddingLeft", "paddingRight"]) {
try { slide.applyToken(margin, [side]); } catch { flex[side.replace("padding", "").toLowerCase() + "Padding"] = 96; }
}
penpot.currentPage.root.appendChild(slide);
// Exact font + size re-assert (gotcha #13b / #13)
const font = penpot.fonts.all.find(f => f.name === "Inter");
const variant = font && font.variants.find(v => v.fontWeight === "700");
const h1 = penpot.createText("Retention doubled in Q3");
h1.name = "h1";
if (font) font.applyToText(h1, variant);
h1.fontSize = "88"; h1.lineHeight = "1.1"; h1.letterSpacing = "-1.5"; h1.growType = "auto-height";
// Click → next slide with a slide-in animation (scripts/wireDeckFlow.js does this for every pair)
current.addInteraction("click", {
type: "navigate-to", destination: next,
animation: { type: "slide", way: "in", direction: "left", duration: 300, easing: "ease-out" }
});
// clearFlip — run before returning from every slide build (gotcha #16)
const clearFlip = (sh) => { let n = 0; const walk = (s) => { if (s.flipX) { s.flipX = false; n++; } (s.children || []).forEach(walk); }; walk(sh); return n; };
15. 参考资源
penpot_api_info("Page", "createFlow")、penpot_api_info("Shape", "addInteraction")、penpot_api_info("Board", "waitForLayoutUpdate")、penpot_api_info("Board", "backgroundBlur")、penpot_api_info("Penpot", "uploadMediaUrl")、penpot_api_info("GridLayout")、penpot_api_info("Gradient")。- Penpot 查看模式(
G V、←/→、Shift+F、流程下拉菜单、分享链接)以及“将所选画板导出为 PDF”(Penpot ≥ 2.12)——references/06-flow-and-playback.md。 - 仅供参考(非依赖项):Penpot Hub 上的官方“Penpot slides template”(CC-BY-4.0)。
16. 支持文件
references/:01-deck-brief-analysis.md(阶段 0)、02-deck-styles.md(阶段 0)、03-slide-archetypes.md(阶段 0、2..N)、04-typography-and-grid.md(阶段 1..N)、05-visuals-and-effects.md(阶段 2..N)、06-flow-and-playback.md(阶段 N+1)、07-critique-framework.md(阶段 N+1)、08-anti-rationalization.md、09-error-recovery.md。
scripts/:createDeckPage.js(阶段 1,调用两次)、setupDeckSystem.js(阶段 1)、buildSlide.js(阶段 2..N)、applyDeckEffects.js(阶段 2..N)、wireDeckFlow.js(阶段 N+1)、auditDeckQuality.js(阶段 N+1)。
shared/:visual-effects.md(渐变、玻璃效果、阴影、图像、clearFlip)、design-quality.md(§2 字体工艺、§3 色彩、§6 内容诚信、§7 标识、§8 评分流程)。
规范文件路径。 在原生安装中,shared/… 和 policies/… 指向此工具包内的文件(由安装程序随附);在 Claude Code 插件安装中,它们位于插件根目录 — ${CLAUDE_PLUGIN_ROOT}/shared/…,即本文件上两级目录。