| name | x-figma-extract |
| description | Figma MCPから実装に必要なデータを取得し、プロジェクトのCSSフレームワークに合わせてトークンを引き当て、マッピングファイルに記録するスキルです。 FigmaのURLやnode-idが渡されたとき、デザインと表示の差分を確認するとき、「スタイルが違う」「デザイン通りか確認して」「Figmaと比較して」のような依頼でも積極的に起動してください。 Figma MCPを呼び出す前に、必ずこのスキルの手順に従ってください。
|
| allowed-tools | ["Bash","Read","Write","Edit","AskUserQuestion","mcp__figma__get_design_context","mcp__figma__get_screenshot","mcp__figma__get_metadata","TaskCreate","TaskUpdate","TaskList"] |
figma-extract
このスキルは以下の3点を実施します。
- Figma MCPから対象要素の全データを取得します
- 取得したデータをマッピングファイルに記録します(スタイル・テキスト・レイアウト)
- 実装時に差分を確認するためのスクリーンショットを保存します
実装はスコープに含まれません。
| ファイル | 内容 | 参照タイミング |
|---|
references/project-tokens.md | フレームワーク別のFigmaトークン引き当て方法 | Step 1・Step 3 |
references/project-save-format.md | 保存先・ファイルテンプレート・完成形サンプル | Step 2・Step 3 |
references/figma-output.md | Figma出力の読み方(sparse処理・テキスト改行・レイアウト算出) | 毎Step |
タスク登録(実行開始時に必ず実施)
フローを開始する前に、全ステップをTaskCreateで登録します。各ステップを開始するときTaskUpdateでin_progressへ、完了したときcompletedへ更新します。
| # | subject | blockedBy |
|---|
| 1 | 事前確認: コンポーネント粒度の把握 | — |
| 2 | Step 1: CSSフレームワークを特定してトークンを把握する | 1 |
| 3 | Step 2: Figma MCPからデータを取得して記録する | 2 |
| 4 | Step 3: トークンを引き当ててマッピングファイルを更新する | 3 |
| 5 | Step 4: 差分確認用のスクリーンショットを保存する | 4 |
事前確認:コンポーネント粒度の把握
Step 1を始める前に、AskUserQuestionでコンポーネントの粒度をユーザーに確認します。エージェントもPass 2で独自に判断しますが、ユーザーの意図を先に把握することで精度が上がります。
以下のA→Bのサイクルを、ユーザーが「完了」を選ぶまで繰り返します。
ステップA:追加するか確認(1問)
質問: コンポーネントを追加しますか?
選択肢:
- 追加する
- 完了(これ以上追加しない)
「完了」が選ばれたら繰り返しを終了します。「追加する」が選ばれたらステップBに進みます。
ステップB:詳細の確認(5問)
| # | 質問 | 選択肢 |
|---|
| 1 | URLまたはnode-idを入力してください | 「その他」で自由入力 |
| 2 | このコンポーネントの名前・役割は? | 「その他」で自由入力 |
| 3 | スコープ | サイト共通/カテゴリー共通/ページ固有 |
| 4 | 実装済みか | 実装済み/未実装/不明 |
| 5 | 備考(実装済みの場合はパスも。なければスキップ) | 「その他」で自由入力/なし |
5問目が終わったらステップAに戻ります。
componentNodesへの記録
ユーザーから受け取った情報は、Pass 2でcomponentNodesへ記録する際、以下のフィールドとして追加します。
{
"nodeId": "9856:14163",
"name": "Contents",
"description": "...",
"scope": "page",
"implemented": false,
"notes": ""
}
| フィールド | 値 |
|---|
scope | "site-common"(サイト共通)/"category-common"(カテゴリー共通)/"page"(ページ固有) |
implemented | true(実装済み)/false(未実装)/null(不明) |
notes | 備考テキスト。省略可 |
ユーザーが指定したノードはPass 2の3回判断に優先してcomponentNodesに含めます。ユーザーが指定していない領域はPass 2の3回判断で補完します。
Step 1: CSSフレームワークを特定してトークンを把握する
以下のコマンドを上から順に実行し、最初に出力を返したものがこのプロジェクトのCSSフレームワークです。特定したら、対応する設定ファイルを読んでトークン体系を把握します。
| コマンド | 出力があれば | 次に読むファイル |
|---|
ls tailwind.config.* 2>/dev/null | Tailwind CSS | tailwind.config.ts(または.js)のtheme.extend |
ls panda.config.* 2>/dev/null | Panda CSS | panda.config.ts(または.js)のtokens/semanticTokens |
find src -name "*.css.ts" -maxdepth 4 | head -3 | vanilla-extract | contract.css.tsまたはvars.css.ts |
find src -name "*.module.css" -o -name "*.module.scss" | head -3 | CSS Modules | variables.cssまたは_variables.scss |
Figmaトークンの引き当て方法はreferences/project-tokens.mdを参照します。
Step 2: Figma MCPからデータを取得して記録する
ユーザーが渡したFigmaのURLからnode-idを取り出してget_design_contextに渡します。URLがない場合はユーザーに確認します。返り値の読み方はreferences/figma-output.mdを参照します。
ノードIDの決め方(重要)
ページルートのノードIDを起点にしてはいけません。ページルートから開始するとsparse XMLが連鎖して30件以上のフェッチが発生します。
ユーザーが渡したURLのノードIDをそのまま使います。ユーザーはFigmaで実装対象コンポーネントを選択してURLをコピーしているため、そのノードIDが正しい粒度です。コンポーネントレベルのノードを直接指定すれば、ほぼ1コールでfull JSXが返ります。
スキップするノードをユーザーに確認する(取得前に必ず実施)
取得を始める前にAskUserQuestionで以下を確認します。
「以下のノードは取得をスキップしますか?すでに実装済みの共通コンポーネントはスキップすることで取得コールを削減できます。」
確認する内容は以下の通りです。
- ユーザーが渡したURLに複数ノードが含まれる場合、各ノードについてスキップするかどうかを尋ねます
- Figmaノード名から
Header Footer Nav Browser ad Calendar等の語を含む場合は「実装済みの可能性あり」として選択肢に挙げます
- コードベースを確認して同名のコンポーネントがすでに存在する場合は「実装済み」と明示します
ユーザーが「スキップする」と答えたノードは_index.jsonのuserSkippedNodesに記録し、フェッチしません。
取得手順
-
explore/{page-slug}/figma/raw/とscreenshots/がなければ作成し、_index.jsonを準備します
-
ユーザーが渡したノードIDを対象にget_design_contextを呼び出します
-
レスポンスを受け取ったらすぐにディスクへ保存します({nodeId}.txtまたは{nodeId}.xml)。保存前に次のコールに進まないでください
-
保存したファイルの種類に応じてスクリプトを実行し、_index.jsonを更新します。
手動grepや手書き更新ではdata-nameの対応付けが漏れたり件数がずれたりするため、
スクリプト以外の方法で_index.jsonを更新してはいけません。
references/project-save-format.mdに手動コマンドの記述があっても無視してください。
.txt(完全レスポンス)の場合は以下を実行します。
node .claude/skills/x-figma-extract/scripts/update-jsx-nodes.js explore/{page-slug}/figma/raw/{nodeId}.txt explore/{page-slug}/figma/raw/_index.json
.xml(sparseレスポンス)の場合は以下を実行します。
node .claude/skills/x-figma-extract/scripts/update-pending-nodes.js explore/{page-slug}/figma/raw/{nodeId}.xml explore/{page-slug}/figma/raw/_index.json
treeへの追加は引き続き手動で行います(ノード名・type・parent等の意味情報はスクリプトでは補完できないため)
-
check-pending.jsを実行し、exit 0になるまで2〜4を繰り返します
node .claude/skills/x-figma-extract/scripts/check-pending.js explore/{page-slug}/figma/raw/_index.json
-
Pass 2として、全ノードの取得完了後、jsxNodesの完全なリストを見てコンポーネント境界を判断しcomponentNodesに記録します(詳細はreferences/project-save-format.md参照)。この判断を3回繰り返します。
事前確認でユーザーが指定したノードは必ず含めます。ユーザーがscope・implementedを教えてくれた場合はそれも記録します。
| 回 | 観点 |
|---|
| 1回目 | ノード名(PascalCase・既知のコンポーネント名)から境界を判断します |
| 2回目 | 1回目の結果を見ずにゼロベースで、レイアウト構造(親子関係・サイズ・役割)から境界を判断します |
| 3回目 | jsxNodesをゼロベースで再度読み、1・2回目で候補に挙がらなかったノードに絞って検討します |
3回の検討で候補に挙がったノードをすべてcomponentNodesに含めます。ユーザー指定ノードと重複する場合はユーザーの情報(scope・implemented)で上書きします。
Step 3: トークンを引き当ててマッピングファイルを更新する
Step 2で保存したマッピングファイルのスタイル表の「トークン」列を埋めます。引き当て方法はreferences/project-tokens.mdを参照します。完成条件はreferences/project-save-format.mdを参照します。
ダブルチェック(必須)
各属性のトークンをマッピングファイルに記録したら、必ず生データ(.txt)を再度開いて該当属性の値を確認し、記録したトークンが正しいことを照合してから次の属性に進みます。記憶や推測で変換してはいけません。
トークン列に空欄が1つも残らなくなるまで続けます。空欄が残っていれば引き当て作業に戻ります。
Step 4: 差分確認用のスクリーンショットを保存する
mcp__figma__get_screenshotを呼び出し、explore/{page-slug}/figma/screenshots/に保存します。保存したファイルのパスをマッピングファイルの### スクリーンショットに記録します。
以下の2種類を取得します。
| 取得対象 | 用途 |
|---|
| ユーザーが渡したノード(ページ全体または親コンテナー) | レイアウト・隣接要素との関係を確認します |
componentNodesの各ノード | コンポーネント単体の詳細を確認します |
スクリーンショット取得の手順
取得対象は自分で判断せず、必ずスクリプトの出力に従います。
-
check-screenshots.jsを実行して不足リストを取得します
node .claude/skills/x-figma-extract/scripts/check-screenshots.js explore/{page-slug}/figma/raw/_index.json
-
exit 1(不足あり)なら、出力JSONの各nodeIdに対してget_screenshotを呼び出してファイルを保存します
-
check-screenshots.jsを再実行します
-
exit 0になるまで2〜3を繰り返します
exit 0の確認を省略してはいけません。取得したつもりでもファイル保存が失敗している場合があるため、必ずスクリプトで最終確認します。
フレーム寸法をマッピングファイルに記録する
取得したスクリーンショットと後続の実装スクリーンショットを比較するには、同じ横幅が必要です。
get_design_contextの出力、またはmcp__figma__get_metadataでフレームノードのwidth・heightを確認し、マッピングファイルの### スクリーンショットセクションにフレーム寸法を記録します。
### スクリーンショット
- Figmaフレーム寸法: 375×812px(比較時のブラウザビューポート幅として使う)
- figma/screenshots/9676-XXXXX.png
この値はx-figma-implementのStep 6でブラウザビューポートを合わせるために使います。