お疲れ様です。みんみんです。
今、Figma のデザインを Claude Code で実装するためのプラグイン「figma-harness」を作っています。
案件番号を渡すと、案件情報の取得 → 計画 → 実装 → 確認 → commit → MR までを、決まった順番で進めるものです。
今回は「なぜこれを作ったのか」と「どう設計したのか」を書きます。
まだ構築中なので、うまくいっていないところも含めて書いていきます。
目次
はじめに:AI に Figma 実装を頼むときの不安
Figma MCP を使うと、Claude Code がデザインの値を直接読めます。
「これで Figma 実装はほぼ自動になるのでは」と最初は思っていました。
……でも、実案件で使うことを考えると、不安がどんどん出てきました。
- Figma にない値を、それっぽく埋めてしまわないか
- 隣のブロックの余白を流用したり、SP の値を PC から計算したりしないか
- 対象ファイルを grep で探し回って、時間とトークンを使い切らないか
- 既存モジュールを使うべきところで、新しいクラスを勝手に作らないか
- 確認が終わる前に commit してしまわないか
どれも「AI が悪い」わけではありません。
判断の基準と順番が決まっていないから起きることです。
人に頼むときも、新しく入った人にはまず手順と確認ポイントを渡しますよね。
じゃあ、AI にも同じものを渡せばいい。
それを Claude Code 向けに仕組みにしたのが figma-harness です。
設計の考え方は3つ
作るときに決めた方針は、大きく3つです。
- 流れを固定する
- 人が決めることを、先に決めておく
- 出典のない値は書かない
1. 流れを固定する
案件番号を付けて実行すると、Step 0〜11 の順に進みます。
| Step 0 | 環境チェック |
|---|---|
| Step 1〜2 | 案件情報・添付・Figma・対象ファイルの取得 |
| Step 3 | ゲート0:入力の確認 |
| Step 4 | ブランチ名を選ぶ |
| Step 5 | 計画(plan mode)→ ゲート1:計画の承認 |
| Step 6 | 実装 |
| Step 7〜9 | visual check・チェックリスト・レビュー |
| Step 10 | ゲート2:ブラウザで確認 |
| Step 11 | commit → push → MR |
ポイントは、Figma を読むのは計画(Step 5)までに一度だけにしたことです。
計画の段階で、PC・SP の値を出典つきの「差分テーブル」にまとめます。
実装ではそのテーブルだけを見て、Figma を読み直しません。
Figma MCP には呼び出し回数の上限があるので、何度も読み直すとすぐに足りなくなります。
それに、実装の途中で読み直すと、値の出どころが計画と実装の2か所に分かれてしまいます。
「値を決める工程」と「値を使う工程」を分ける。これが狙いです。
2. 人が決めることを、先に決めておく
全部を AI に任せるのではなく、人が確認する場所を3つ置いています。
- ゲート0:対象 URL・仕様の解釈・使う Figma・対象ファイル
- ゲート1:計画(部品ごとに、既存モジュールのまま使う・上書きする・新しいクラスを作る、を選ぶ)
- ゲート2:作業ページをブラウザで見て OK を出す
そして、次のような判断は「自信があっても自分で決めず、ゲートで聞く」と決めました。
- 原稿と Figma が食い違っているときの扱い
- 既存モジュールを使うか、上書きするか、新しいクラスを作るか
- 既存の値・変数と違う Figma の値を採るか
- 頼まれていないファイルを直すなど、案件の範囲を変えること
さらに、各ゲートの最後に「自分で決めたこと」の一覧を出させています。
小さな判断でも一覧に出るので、違っていたらその場で止められます。
ちなみに、ユーザーが「進めて」「任せる」と言っても、ゲートは省略しない、とも書いています。
急いでいるときほど確認を飛ばしたくなるので、ここは最初から決めておきました。
3. 出典のない値は書かない
色・余白・font-weight・文言・alt は、どこから取った値なのかを決めています。
| 色・余白・サイズ・font-weight・枠線 | Figma MCP(座標と照合したもの) |
|---|---|
| 文言・太字範囲・文字色 | 原稿 |
| alt | 画像を実際に開いて決める |
| クラス名・変数・mixin | 既存の SCSS |
| どれにもない | 実装を止めて聞く |
原稿と Figma が食い違ったときは、文言は原稿、画像・数値は Figma を正とします。
ただし、それも単独では決めず、差異を一覧にして依頼元に確認します。
Figma MCP の出力は React + Tailwind の参考コードなので、そのままは使えません。
特に SP は、変数の値が PC のまま出てくることがあります。
なので、コードの値は get_metadata の座標と照合してから使うようにしています。
調べ方も道具にする
AI に「このページのファイルを探して」と頼むと、リポジトリ全体を grep で探し回りがちです。
探し回るほど、時間もトークンも使ってしまいます。
そこで、調査用のスクリプトを用意しました。
- URL から、そのページの描画ファイル・読み込んでいる CSS と元の SCSS・使えるモジュールを出す
- クラスの定義場所と CSS の値を出す(SCSS のネストを展開)
- 古い URL・パス・ファイル名の参照が残っていないかを探す
flow の中では「新しいスクリプトを書かない」「grep で探さない」と決めて、この3つを使わせています。
毎回同じ方法で調べることで、結果のばらつきを減らすのが狙いです。
確認の工程も同じ考え方です。
visual check では Playwright で PC・SP の computed 値を取り、差分テーブルと突き合わせます。
「見た目で合っていそう」ではなく、値で確かめる。
うまくいかなかったこと:指示だけでは守られない
ここまでの内容は、最初は全部 skill(手順書)に書いていました。
これで大丈夫だろう、と。
でも、正直それだけでは守られませんでした。
「計画の承認前は編集しない」と書いてあっても、編集を始めてしまう。
「grep で探さない」と書いてあっても、探し始めてしまう。
え、書いてあるのに? という感じです。
そこで考え方を変えました。
守ってほしいことの一部は、指示ではなく hook で機械的に止める。
Claude Code の PreToolUse hook で、ツールを実行する前にチェックします。
| ファイル編集 | 計画の承認(ゲート1)前は止める |
|---|---|
| commit | 確認が揃う前は止める。形式に合わないブランチ名も止める |
| 検索 | リポジトリ全体の検索を止める |
| サブエージェント | 起動を止める |
| ローカル環境の操作 | AI が自分で直そうとするのを止める |
どこまで進んだかは、リポジトリ内の状態ファイルに書きます。
hook はこのファイルを見て、通すか止めるかを決めます。
---
step: 1 案件情報
branch:
input_confirmed: false
plan_approved: false
visual: false
checklist: false
reviewed: false
approved: false
---
たとえば plan_approved が true になるまでは、リポジトリ内のファイルを編集できません。
visual・checklist・reviewed・approved が揃うまでは、git commit もできません。
この状態ファイルは flow の最後に消えるので、hook が止めるのは flow の間だけです。
普段の作業まで縛るわけではありません。
指示と仕組みの使い分け
ここから、「書けば守られる」ものと「止めないと守られない」ものを分けて考えるようにしました。
- 手順書(skill)に書くもの:進め方、判断の基準、値の出典、書き方の規約
- hook で止めるもの:順番を飛ばすと取り返しがつかない操作(編集・commit・環境の操作)
全部を hook にすると、柔軟さがなくなって使いにくくなります。
逆に全部を手順書に任せると、肝心なところで飛ばされます。
「どこを機械で止めるか」を選ぶのが、ハーネス作りの大事なところだと考えています。
流れとしてはこんな形です。
まとめ
figma-harness は、Figma 実装を AI に「丸投げ」するためのものではありません。
人が判断すべきところで必ず止まり、それ以外は決まった手順で進める。
そういう仕組みです。
- 流れを固定して、Figma を読む工程と実装する工程を分ける
- 人が決めることはゲートで聞き、AI が自分で決めたことは一覧で出す
- 出典のない値は書かない
- 指示だけで守られないところは、hook で機械的に止める
まだ構築中なので、これからも手を入れていきます。
AI に作業を任せるときの「どこまで任せて、どこで止めるか」を考えるうえで、参考になれば嬉しいです。
