mcpField
P
penpot-build-screen

penpot-build-screen

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

penpot-build-screen について

既存のデザインシステムに沿って、ブリーフから画面を作る Penpot スキルです。フレックスレイアウトで段階的に構築し、コンポーネントとセマンティックトークンを再利用しながら、視覚確認と品質監査を行います。

主な機能

  1. 01既存のトークンとコンポーネントを確認
  2. 02画面をセクションごとに構築
  3. 03コンポーネントとセマンティックトークンを再利用
  4. 04フレックスまたはグリッドレイアウトを使用
  5. 05確認用の書き出しと品質監査

活用シーン

  1. 01プロダクトブリーフから画面を作成
  2. 02既存の Penpot デザインシステムを拡張
  3. 03レイアウト、トークン、間隔の整合性を確認

MCP 対応

`execute_code` を通じて Penpot MCP ツールを使用します。`export_shape` による視覚確認と、`penpotUtils.shapeStructure` による構造の確認が含まれます。

インストール

コマンドをコピーしてターミナルで実行します。

$npx skills add https://github.com/penpot/penpot-ai-kit --skill penpot-build-screen

インストール後、Claude Code で/penpot-build-screenを入力して読み込まれたか確認します。

同梱ファイル

SKILL.md と一緒にインストールされる参考資料やスクリプト。

references/
01-brief-analysis.md
02-style-profiles.md
03-layout-composition.md
04-component-recipes.md
05-critique-framework.md
06-anti-rationalization.md
07-error-recovery.md
scripts/
assembleScreen.js
auditScreenQuality.js
buildSection.js
createScreenFrame.js
setupOrReuseSystem.js

詳細

penpot-build-screen — ブリーフからシステム内画面へ

1. タイトルと仕組み

penpot-build-screen はブリーフから洗練されたシステム内画面を作成します。変更はすべて execute_code を通じて行い、export_shape で視覚的に検証し、 penpotUtils.shapeStructure で構造を読み取ります(ツールの全容:shared/penpot-mcp-tool-reference.md)。まず 既存のデザインシステム(penpot-foundations/ローカルライブラリ経由のトークンとコンポーネント)を 検出し、その後、フレックスボード内でセクションごとに画面を構築し、トークンを適用して コンポーネントを再利用します。画面全体を一度の呼び出しで生成することはありません。

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

システムを再利用し、段階的に構築します。 生のシェイプよりも既存のコンポーネントやセマンティックトークンを優先してください。セクションを1つ構築したら、export_shape でチェックポイントを作成してから次へ進みます。システムが存在しない場合は、最小限のものだけを初期構築し、実質的な作業は penpot-foundations に引き継いでください。

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

ツールの全容:shared/penpot-mcp-tool-reference.md。主な呼び出し:画面とセクションには penpot.createBoard()/addFlexLayout()、コンポーネントの再利用には penpot.library.local.components と comp.instance()、トークンの適用には shape.applyToken、チェックポイントには export_shape('selection'|'page') を使用します。

4. プラグイン API の基本

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

  • 画面とセクションはフレックスレイアウトを持つボードです。追加順序と間隔、配置/均等配置を使って構成します。
  • component.instance() でコンポーネントを再利用します。システムのパーツを生のシェイプとして描き直さないでください。
  • #3 テキストの自動サイズ調整 — resize()(fixed に設定される)を実行した後に、growType を auto-width/auto-height に設定します。
  • #4 フレックスは子要素の x/y を上書きします — ストレッチ/マージンには layoutChild を使用します。
  • 色/間隔/角丸/書体はセマンティックトークンに適用し、ハードコードは避けてください。
  • #11 新しい Board はすべて不透明な白の塗りつぶしで作成されます — これはこのスキルの重大な失敗要因です。 createBoard() は fills = [{ fillColor: "#FFFFFF", fillOpacity: 1 }] を設定します。そのままにすると、構造用ラッパーの四角い白い角が角丸の子要素の背後にはみ出し、角丸が壊れて見えます。また、白をそのまま保持したレイアウト用ボードはダークモードに切り替わりません(トークンがなく、システムから外れています)。塗りつぶしの方針: ボードごとに決めます — 構造用ボード(セクション、行、ラッパーなど、レイアウトのみを担うもの)は board.fills = [] にします。サーフェス(画面の背景、カード、シート、ボタン)は、リテラル値ではなく color.bg.* トークンを適用します。レイアウト用コンテナーはデフォルトで透明にします(shared/modes-and-policies.md)。
  • #13b フォントの完全一致 — penpot.fonts.all.find(f => f.name === "…") を使用します。findByName は部分文字列検索です。
  • #15 — layoutChild.* は appendChild の後にのみ設定します。openPage は非同期です(2回呼び出すプロトコル:作成して開き、その後 createBoard の前に currentPage.id をアサートします)。
  • #16 — セクションごとに clearFlip を実行します(塗りつぶしサイズの子要素で flipX = true が発生することがあります。標準ヘルパーは shared/visual-effects.md を参照)。
  • #17 — ジオメトリを読み取る前に await board.waitForLayoutUpdate() を実行します(sleep-100ms の慣用パターンに代わる方法です)。
  • #18 — 画像の塗りつぶし:const img = await penpot.uploadMediaUrl(name, url); shape.fills = [{ fillOpacity: 1, fillImage: img }] を設定し、次の呼び出しで検証します — shared/visual-effects.md を参照してください。
  • 不慣れなシグネチャは、まず penpot_api_info で確認してください。

5. トークンを考慮したブリーフの契約

  • コンテキスト — 製品、対象ユーザー、プラットフォーム、ブランドの雰囲気。
  • 目的 — 対象となる単一画面と、ユーザーの主な目標。
  • 入力 — コンテンツ/セクション、既存のトークンとコンポーネント、スタイルプロファイル、ビューポートサイズ。
  • 制約 — 既存のコンポーネントを使用すること、グリッドに沿った間隔、セマンティックトークンのみを使用すること、禁止パターン、shared/design-quality.md §7 に記載された兆候を含めないこと、strict anti-slop が有効な場合は、方向性の決定ステップで拒否されたキーを含めないこと(shared/anti-slop.md §1)。
  • 受け入れ基準 — 明確な階層構造、4px のリズム、AA コントラスト、システムの再利用、レスポンシブ対応の意図が明記されていること、7 つすべての評価軸で design-quality スコアが 3 以上であること(shared/design-quality.md §8)。満たさない場合は、弱い評価軸を明示してください。strict anti-slop が有効な場合は、slop スコアが 35 以下であること(penpot-anti-slop diagnose)。

一般的なものではなく、意図的な美的判断を行うシニアプロダクト/ビジュアルデザイナーとして振る舞ってください。

6. 必須のワークフロー

ビジュアルの自己レビュー(必須): ビジュアルを提示するすべての ✋ チェックポイントの前に、 shared/visual-self-review.md のエクスポート → 確認 → 修正のループを実行してください。作成したばかりの単位を エクスポートし、チェックリストに照らして画像を自分で確認し、目に見える不備を修正します(最大 2 回の イテレーション)。残っている不備があれば、その内容を明示したうえで同じエクスポートを提示してください。

フェーズ 0 — 検討。 high_level_overview を実行し、トークン/コンポーネントを確認します(scripts/setupOrReuseSystem.js)。ブリーフを分析します(references/01-brief-analysis.md)。スタイルプロファイル(references/02-style-profiles.md)と名前付き画面スケルトン(shared/design-quality.md §5)を選択します。このセッションで以前に作成した画面がないか台帳を確認し、多様性ルールを適用します(1 つ以上の軸を変え、どの軸かを述べること)。Anti-slop のオプトイン: 保存済みの設定(penpot-anti-slop → scripts/antiSlopPrefs.js)を読み込みます。設定がなく、ブリーフにも記載がない場合は、shared/anti-slop.md §0 にある質問を(ユーザーの言語で、ファイルごとに 1 回)尋ね、回答を保存します。設定が on の場合は、プロファイルとスケルトンを選ぶ前に方向性の決定ステップ(penpot-anti-slop references/02-direction-playbook.md)を実行し、そこで拒否されたキーを制約に反映します。✋ チェックポイント:ブリーフ、スタイル、スケルトン、セクション一覧(strict モードが有効な場合は方向性のブロックも含む)を確認します。

フェーズ 1 — フレーム。 scripts/createScreenFrame.js で画面ボードを作成します(冪等。ID を返し、背景/間隔/パディングのトークンを紐付けます)。ビューポートサイズを設定します。✋ チェックポイント。

フェーズ 2..N — セクション。 scripts/buildSection.js を使用して、トークン化されたフレックスボードとして各セクションを作成し、コンポーネントを再利用します。execute_code の呼び出し 1 回につき 1 セクションを作成します。各セクションの後に ✋ チェックポイント(export_shape)。

フェーズ N+1 — 組み立てと評価。 scripts/assembleScreen.js でセクションを組み立てます。scripts/auditScreenQuality.js で、レイアウトの網羅性(すべてのボードに flex/grid があること)、トークンの紐付け、グリッドに沿った間隔、命名を確認します。boardsWithoutLayout が空でない場合はゲートに失敗します。完了を報告する前に、フラグが付いた各ボードにレイアウトを追加してください。続いて、スコア付き評価(references/05-critique-framework.md)を実行します。最終エクスポートを shared/design-quality.md §8 の 7 つの評価軸それぞれで 1~5 点で評価します。いずれかの軸が 3 未満の場合は、対象を絞って修正します(最大 2 回)。その後、design-quality レポートを出力します(shared/report-schemas/design-quality-report.schema.json に従った Markdown + JSON 形式とし、台帳にも反映します)。strict モードが有効な場合: 画面ボードに対して penpot-anti-slop diagnose を実行し、その slop スコアをレポートに含めます(distinctiveness 軸に反映されます)。ワークフロー外では、スコアが 35 を超える場合、完了を宣言するのではなく、優先して修正すべき項目を提示します。レポートを出力します。

7. 重要なルール

  1. デフォルトでは Flex — すべてのコンテナはレイアウト Board です。 Board を作成したらすぐに、子要素を追加する前に、flex(addFlexLayout())または grid(addGridLayout())レイアウトを設定してください。画面のルート、すべてのセクション、そして入れ子になったすべてのグループ(カード、行、リスト、統計情報のまとまり、フォームフィールド、ボタングループ)が対象です。UI 要素の配置に絶対座標 x/y を使うこと、また UI のレイアウトに単なる Group を使うことは、絶対に避けてください。レイアウトのない Board はバグです。Phase N+1 の監査(boardsWithoutLayout)では、該当する Board が1つでもあるとビルドに失敗します。
  2. 生のシェイプを作成する前に、既存のコンポーネントを再利用してください。
  3. セマンティックトークンにバインドし、色、間隔、角丸、文字スタイルをハードコードしないでください。
  4. 1回の呼び出しにつき1つのセクションを作成し、export_shape でチェックポイントを設けてください。
  5. すべての間隔を4pxグリッドに合わせ、一貫したリズムを保ってください。
  6. ここでデザインシステム全体を立ち上げないでください。penpot-foundations に引き継いでください。
  7. レスポンシブ対応の意図(サイズ設定:fill/auto/fix)を明示してください。

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

画面 = ルート flex Board(縦方向) → セクション Board(それぞれ独自の flex) → コンポーネントのインスタンス + トークン化されたプリミティブ。構成は明確な視覚的階層に従います。主要なアクションを目立たせ、コンテンツをグループ化し、間隔スケールに沿って余白を設け、セマンティックな文字スタイルのトークンを使用します。

9. モードとポリシー

デフォルトはreviewです。ジオメトリ/レイアウトの変更には、常にチェックポイントが必要です(shared/modes-and-policies.md)。

10. 状態管理

RUN_ID の下に台帳を保持します。内容は phase、screenBoardId、sections:[{name,id,done}]、styleProfile、skeleton、designQuality(§8 のレポートオブジェクト)、antiSlop(pref、direction、reports[] — strict mode が有効な場合)です。オプトインの設定自体は、ファイル全体に適用されるプラグインデータ penpot-ai → prefs.antiSlop です。再開時は、構造を読み直してください。

11. ユーザーのチェックポイント

フェーズ後成果物確認事項
0(pref 未設定)anti-slop のオプトインに関する質問(shared/anti-slop.md §0)ありきたりな AI 風の見た目を避けますか?
0brief + style + skeleton + sections(strict の場合は direction ブロックも)方向性を承認しますか?
1空のフレーム export_shapeフレーム/ビューポートを承認しますか?
各セクションセクションの export_shapeセクションを承認しますか?
組み立て画面全体の export_shape + スコア付きの批評(7つの評価軸)承認しますか/反復しますか?

12. 命名規則

shared/naming-conventions.md:レイヤーにはセマンティック HTML(header、main、section、nav、button)を使用し、画面の Board にはビュー名(Dashboard)を付けます。

13. 合理化を防ぐための表

言い訳なぜ間違っているのか対策(中断)
「コンポーネントを使わずに、ボタンをさっと描こう。」生のシェイプはシステムとの一貫性が崩れます。既存のコンポーネントをインスタンス化してください。再発明より再利用を優先します。
「間隔/色をハードコードしたほうが速い。」リズム/テーマ設定/ガバナンスが損なわれます。セマンティックトークンにバインドし、間隔を4pxに合わせてください。
「画面全体を一度に生成しよう。」一度に生成した出力はありきたりで、監査できません。チェックポイントを設けながら、セクションごとに構築してください。
「中央揃えのカードとありきたりなグラデーションで問題ない。」出力が似通うことで、特徴のないブランドらしさに欠ける UI になります。意図的なスタイルプロファイルを適用し、美的な選択に理由を持たせてください。
「ユーザーは忙しいから、anti-slop の質問は省こう。」strict mode を選ぶのはユーザーです。どちらかを推測しても間違いです。prefs.antiSlop を読み取ってください。未設定なら、1回だけ質問します(shared/anti-slop.md §0)。
「ここでトークンをさっと設定しよう。」Foundations の役割は専用のスキルにあります。些細な作業を除き、penpot-foundations に引き継いでください。
「x/y で配置したほうが速いから、そうしよう。」絶対座標はサイズ変更、リフロー、テーマ設定に対応できず、システムにも沿いません。flex/grid の Board で囲み、追加順とギャップ/整列で配置してください。
「これらをまとめるだけなら、単なる Group で十分。」Group はレイアウトを行わず、要素を囲むだけです。addFlexLayout() を使った Board を使用してください。監査ではレイアウトのない Board が検出されます。
「この小さなコンテナにレイアウトは必要ない。」すべての UI コンテナには、リズムとレスポンシブ対応のためにレイアウトが必要です。子要素を追加する前に、必ず flex/grid を設定してください。例外はありません。

14. ヘルパーコードスニペット

// Screen frame (Phase 1)
const screen = penpot.createBoard();
screen.name = "Dashboard";
screen.resize(1440, 1024);
const flex = screen.addFlexLayout();
flex.dir = "column";
flex.horizontalSizing = "fix"; flex.verticalSizing = "auto";
penpot.currentPage.root.appendChild(screen);         // append first (#7); layoutChild only after append (#15)
// SPACING: bind tokens, never literals (#8: padding tokens bind on ≥ 2.17; numeric mirror + ledger exception otherwise)
const gap = penpotUtils.findTokenByName("spacing.24");
if (gap) screen.applyToken(gap, ["rowGap"]); else flex.rowGap = 24;
const pad = penpotUtils.findTokenByName("spacing.32");
const FLEX_PROP = { paddingTop: "topPadding", paddingBottom: "bottomPadding", paddingLeft: "leftPadding", paddingRight: "rightPadding" };
for (const side of Object.keys(FLEX_PROP)) {
  try { if (!pad) throw new Error("no token"); screen.applyToken(pad, [side]); }
  catch (e) { flex[FLEX_PROP[side]] = pad ? Number(pad.resolvedValue) : 32; }   // record { kind: "padding-mirrors-token" } in the ledger
}
// FILL POLICY (gotchas #11): the screen root is THE one surface — bind its bg to a token so it flips in
// dark mode. Every section nested inside stays transparent (buildSection.js clears their default white).
screen.fills = [];                                   // drop Penpot's default opaque #FFFFFF
const bg = penpotUtils.findTokenByName("color.bg.default");
if (bg) screen.applyToken(bg, ["fill"]);             // bound surface, not a literal
storage.bs = { screenBoardId: screen.id };
return { screen: screen.id, bgBound: !!bg, gapBound: !!gap, padBound: !!pad };

15. 参考リソース

  • penpot_api_info('Board')、penpot_api_info('LibraryComponent')、penpot_api_info('Text')。

16. 関連ファイル

references/: 01-brief-analysis.md、02-style-profiles.md、03-layout-composition.md、04-component-recipes.md、05-critique-framework.md、06-anti-rationalization.md、07-error-recovery.md。エフェクト、画像プレースホルダー、グラデーションについては shared/visual-effects.md を参照してください。 scripts/: setupOrReuseSystem.js、createScreenFrame.js(フェーズ 1 のフレーム:冪等、トークンに紐づく背景/間隔/パディング、台帳)、buildSection.js、assembleScreen.js、auditScreenQuality.js。

ドクトリンのパス。 ネイティブインストールでは shared/… と policies/… はこのバンドル内のパスとして解決されます(インストーラーによってベンダー化されます)。Claude Code プラグインとしてインストールした場合は、プラグインのルートにあり、このファイルから 2 つ上のディレクトリにある ${CLAUDE_PLUGIN_ROOT}/shared/… がパスになります。

コメント