mcpField
P
penpot-build-deck

penpot-build-deck

github.com/penpotデザイン・UI10841 回インストール3 週間前に更新
リポジトリ

penpot-build-deck について

penpot-build-deck は、ブリーフから Penpot 上の編集可能なスライドデザインを作るスキルです。1 回の呼び出しで 1 枚ずつ段階的に作成し、書き出しを確認して、完成したボードを再生可能なフローにつなぎます。

主な機能

  1. 01スライド全体のアウトラインを先に計画
  2. 02編集可能な 1920×1080 のスライドボードを作成
  3. 03デックトークンとタイポグラフィを適用
  4. 04書き出し画像で各スライドを確認
  5. 05レイアウトの多様性と品質を検査
  6. 06スライドを再生可能なフローに接続

活用シーン

  1. 01ブリーフから編集可能なプレゼンテーションを作成
  2. 02レビューを挟みながらスライドを段階的に構築
  3. 03Penpot 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.md
02-deck-styles.md
03-slide-archetypes.md
04-typography-and-grid.md
05-visuals-and-effects.md
06-flow-and-playback.md
07-critique-framework.md
08-anti-rationalization.md
09-error-recovery.md
scripts/
applyDeckEffects.js
auditDeckQuality.js
buildSlide.js
createDeckPage.js
setupDeckSystem.js
wireDeckFlow.js

詳細

penpot-build-deck — ブリーフから再生可能なスライドデッキを作成

1. タイトルと仕組み

penpot-build-deck はブリーフを、Penpot 上に実際に編集できるデザインとして保存されるプレゼンテーションに変換します。専用ページにスライドごとに 1920×1080 のボードを1つ作成し、deck.* トークンセットでトークン化し、フローに接続して、Penpot のビューモードでデッキを再生できるようにします(←/→、Shift+F で全画面表示)。PDF にもエクスポートできます。すべての変更は execute_code 経由で行います。export_shape で見た目を検証します(スライドごとに行い、ページ全体は決して対象にしません)。構造は penpotUtils.shapeStructure で読み取ります(ツール全体の概要:shared/penpot-mcp-tool-reference.md)。Penpot に「スライドモード」はありません。このスキルがデッキ作成ツールそのものです。アウトライン → デッキシステム → スタイルの確定 → スライドを数枚ずつ作成 → フローと品質チェック、という手順で進めます。

2. 最も重要な唯一のルール

アウトライン全体を計画してから、1回の呼び出しにつきスライドを1枚作成します。 1回の execute_code でデッキを生成してはいけません。スライド1~3はスタイル確定の段階です。それ以降はすべて、ここでの決定を引き継ぎます。残りは3~5枚ずつ作成し、各チェックポイントの前にすべてのスライドをエクスポートして、実際に確認してください。また、AI生成スライドにありがちな特徴(タイトル下のアクセント線、装飾的なバー、中央揃えの本文、テキストだけのスライド、同じレイアウトの連続)を避けてください。

3. Penpot MCP ツールリファレンス

ツール全体の概要:shared/penpot-mcp-tool-reference.md。主な呼び出し:penpot.createPage() / openPage()(2回呼び出すページプロトコル);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. Plugin API の要点

注意点の番号は shared/plugin-api-gotchas.md を参照してください。

  • #15 ページの対象指定 — このスキルで最も致命的な失敗要因です。 デッキは専用ページに作成します。別のページ上で作成されたボードは移動できません(ページをまたぐ appendChild は何も起こらず、エラーも出ません)。 scripts/createDeckPage.js は2回呼び出すプロトコルを実行します。呼び出し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. トークンを意識したブリーフの契約

  • コンテキスト — 対象者、機会、所要時間、会場/画面、言語。
  • 目的 — 対象者に必ず持ち帰ってもらう一つのメッセージと、依頼事項/CTA。
  • 入力情報 — 概要(スライドごとに1行)、出典付きの事実と数値、出典を明記した引用、画像のURL(または「プレースホルダー」)、再利用する既存のトークン/コンポーネント/フォント。
  • 制約 — 数値を捏造しないこと。フォントはpenpot.fonts.allに存在すること。すべてのスライドにビジュアルを入れること。禁止事項:タイトル下のアクセントライン、装飾用のバー/ストライプ、本文の中央揃え、デフォルトの青、クリーム色の背景、テキストのみのスライド。deck.*トークンのみ使用すること(グラデーション/シャドウ/ガラス表現はリテラルとして台帳に記録)。厳格なアンチスロップを有効にすること。方向性を決めるステップで却下された項目(shared/anti-slop.md §1、penpot-anti-slopのreferences/04-deck-tells.mdにあるデッキの指標)を確認すること。
  • 受け入れ基準 — すべてのスライドを、NN-archetype-slugという名前の1920×1080のボードにすること。各スライドに1つ以上のビジュアルを入れること。同一のアーキタイプを連続させないこと。デッキ内で同じアーキタイプを40%超使用しないこと。文字サイズの下限は20 px、本文は28 px以上。コントラスト比は、24 px以上または18.67 px以上の太字テキストで3:1以上、それ未満では4.5:1以上。フローはDeckクリックで次へ進むように接続すること。7つすべての評価軸でデッキ品質スコアを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) を分析します:スライド数の上限、伝えるべき1つのメッセージ、アウトライン表 n | archetype | title | key content | visual | tone、トーンの流れ、モチーフ。デッキのスタイル (references/02-deck-styles.md) を選び、多様性の事前チェック (references/03-slide-archetypes.md) を実行します。 Anti-slop のオプトイン: 保存済みの設定(penpot-anti-slop → scripts/antiSlopPrefs.js)を読み取ります。未設定で、概要にも回答がない場合は、shared/anti-slop.md の §0 にある質問を一度だけ(ユーザーの言語で)尋ね、設定を保存します。on の場合は、デッキスタイルを選ぶ前に 方向性 のステップ(penpot-anti-slop の references/02-direction-playbook.md + 04-deck-tells.md)を実行し、拒否されたキーを制約に追加します。 ✋ チェックポイント:アウトライン + スタイル + トーンの流れ + スライド数(+ strict の場合は方向性ブロック)の承認。

フェーズ 1 — デッキシステム。 scripts/createDeckPage.js(PHASE=create、その次の呼び出しで PHASE=verify)。scripts/setupDeckSystem.js:トークンセット deck(既存のブランドトークンがあればエイリアスとして使用)、フォントの解決、任意のマスターコンポーネント。新しいトークンはここで提案し、黙って作成することはありません。✋ チェックポイント:トークン + フォントの承認。

フェーズ 2 — スタイルの確定。 scripts/buildSlide.js(背景の装飾には scripts/applyDeckEffects.js も使用)で 01-cover-…、02-agenda-…、最初のコンテンツスライドを作成し、1回の呼び出しにつき1スライド作成します。それぞれをエクスポートして自己レビューします。✋ スタイル確定チェックポイント — 以降にスタイルを変更する場合は、このチェックポイントをやり直します。

フェーズ 3..N — バッチ。 1バッチあたり3〜5スライド、1回の呼び出しにつき1スライドとし、毎回 clearFlip を実行します。バッチの後、各スライドをエクスポートし、直前のスライドと照らし合わせて多様性ルールを確認します。画像 URL は applyDeckEffects.js でアップロードし、次の呼び出しで確認します。✋ バッチごとにチェックポイントを設けます。

フェーズ N+1 — 接続、ゲート、批評。 scripts/wireDeckFlow.js(順序、フロー Deck、クリック → 次へ、自動進行は任意、セクションごとのフロー)。scripts/auditDeckQuality.js — pass 以外のゲート結果の場合、「完了」としてはいけません。その後、採点付き批評 (references/07-critique-framework.md) を実施します:7つの評価軸 + 単調さの確認。いずれかの評価軸が3未満の場合は、対象を絞って修正(最大2回)し、shared/report-schemas/deck-quality-report.schema.json に従って Markdown + JSON を作成し、台帳にも反映します。strict モードがオンの場合は、デッキページで penpot-anti-slop の診断(MODE = "deck")を実行し、slop スコアを含めます。PDF のエクスポート手順と共有リンクの手順 (references/06-flow-and-playback.md) を提示します。✋ 最終チェックポイント。

7. 重要なルール

  1. execute_code の呼び出し1回につき、スライドは1枚です。 アウトライン全体を計画し、キャンバスは1枚ずつ作成します。
  2. すべてのスライドは 1920×1080 の Board とし、名前を NN-archetype-slug に設定し、showInViewMode = true、clipContent = true として、デッキページのコンタクトグリッドに配置します。
  3. 塗りつぶしポリシー(#11):スライドボードは deck.bg.<tone> にバインドします。グループ化コンテナは透明にします。
  4. まずトークンを使用:色、文字サイズ/フォントファミリー、間隔、角丸には deck.* を使用します。グラデーション、ガラス風の塗りつぶし、シャドウはバインドできません。それぞれについて、派生元のトークンを記した exceptions エントリを台帳に追加します。
  5. 各スライドに1つ以上の視覚要素(図形、画像/プレースホルダー、140 px 以上の統計数値、グラフのプレースホルダー、コンポーネントインスタンス)を配置します。テキストのみのスライドはゲートを通過できません。
  6. バリエーションのルール:連続するスライドでは、アーキタイプ/アンカー/トーンのうち1つ以上を変えます。同じアーキタイプを連続して使用してはいけません。また、同じアーキタイプがデッキの40%を超えてはいけません。
  7. 文字サイズの下限は20 px、本文は28 px 以上、タイトルは72~96 px(references/04-typography-and-grid.md)です。フォントファミリーは2種類以下、ウェイトは3種類以下にします。文頭のみ大文字を使用し、本文は左揃えにします。
  8. 内容は事実に忠実に:数値はブリーフに記載されたもののみを使用し、それぞれ出典の行を付けます。引用には出典を明記します。ダミーテキストや「Item 1」は使用しません。
  9. 画像:ユーザーが URL を提示していない場合は、ラベル付きプレースホルダーを使用します。アップロードは次の呼び出しで検証し、失敗した場合は報告して、黙って差し替えないでください。
  10. 避けるべき表現を使わない:タイトル下のアクセント線、装飾用のバー/ストライプ、中央揃えの本文、デフォルトの青、クリーム色の背景、白地に紫のグラデーション、連続する同一レイアウト。
  11. 各スライドの後に clearFlip(slide) を実行し、ジオメトリを読み取る前に await waitForLayoutUpdate() を実行します。
  12. フローの設定も「完了」の一部です:wireDeckFlow.js を実行するまでは、最終チェックポイントに進めません。
  13. §11 に従ってチェックポイントを設定します。「問題ありません」という承認は、直前に提示したバッチにのみ適用されます。

8. ドメインアーキテクチャ

ページ Deck — <title> → 4列のコンタクトグリッド上のスライドボード(x = (i % 4)·2080、y = ⌊i/4⌋·1240) → 各スライド:余白を 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. モードとポリシー

デフォルトは レビュー です。ここで安全に行える操作は、スライドボードの名前を 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[]。オプトイン設定自体はファイル全体に適用されるプラグインデータ penpot-ai → prefs.antiSlop)を含めます。storage.deck には、セッション用の ID のコピーが保存されます。再開する際は、台帳を読み直し、createDeckPage.js の PHASE=verify を再実行し、名前(^\d{2}-)からスライド一覧を再構成して、最初の done: false のスライドから続行します(shared/state-management.md)。

11. ユーザーによる確認ポイント

フェーズ後成果物確認事項
0(設定なし)汎用的なAI風の見た目を避けるか確認する質問(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枚のスライドを一度の呼び出しですべて作ります。同じコードなので。」一括作成したデッキは監査できず、どのスライドも同じ仕上がりになります。1回の呼び出しで1枚作成し、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、2 回呼び出し)、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 プラグインとしてインストールした場合は、プラグインのルート(このファイルから 2 つ上のディレクトリにある ${CLAUDE_PLUGIN_ROOT}/shared/…)に配置されます。

コメント