# Figma Comment Map

> Figmaファイルの全コメントをREST APIで取得し、画面ごとのスクリーンショットにコメントピンを復元したHTML/PDFレポートを生成するスキル。FigmaのDM通知はメンション外のコメントを届けないため、通知の有無に依存せず全件を突合できる。コメントが大量に溜まったファイルの棚卸し・レビュー会の資料づくりに使う（例：/figma-comment-map <FigmaのURL>）。

- Skill: `sugawaramasaya/figma-comment-map` (Agent Skill, multi-file: 2 files)
- Install (CLI): `npx skillmds@latest add sugawaramasaya/figma-comment-map`
- Raw SKILL.md: https://api.skillmd.com/api/skills/sugawaramasaya/figma-comment-map/raw
- Safety review: pending
- Works with: Claude Code, Claude.ai, OpenAI Codex
- Category: Design & Media
- Author: sugawaramasaya (https://skillmd.com/u/sugawaramasaya)
- Updated: 2026-09-22
- Page: https://skillmd.com/skills/sugawaramasaya/figma-comment-map

---


# /figma-comment-map — Figmaコメントを画面ごとに棚卸しする

Figma の URL を渡すと、**全コメントを画面ごとにまとめたレポート**（HTML／PDF）を出す。

## なぜ必要か

Figma の Slack 通知には **2種類あり、混同すると取りこぼす**。

| 種類 | 届くもの |
|---|---|
| デフォルト通知（Figma アプリからの DM） | 自分がメンションされたコメント / 招待だけ |
| **チャンネル購読**（`/figma subscribe`） | file 単位で **Comments, replies, @mentions** |

つまり **DM だけに頼っている運用に穴がある**。CC 外のコメントは DM に来ないので、
Slack を見ているだけでは永久に気づけない。

実例：あるファイルで実装担当者が 45分間に 19件のコメントを連投したが、そこに `@自分` が
含まれていなかったため DM は 1件も来ず、翌日の返信（＝自分が参加したスレッド）だけが届いた。
**通知が来た数件から全体像を推測できてしまう**のが一番危ない。

→ 恒久対策は Slack チャンネルに file を購読させること（下記「取りこぼしを構造的に防ぐ」）。
このスキルの役割は**購読の有無に依存しない全件突合**と、画面ごとの棚卸し。
購読通知の取りこぼし報告もフォーラムに上がっているので、突合の手段は別に持っておく価値がある。

## 使いどき

- コメントが溜まったファイルを棚卸ししたい（「どの画面の話か把握できない」状態）
- レビュー会・仕様確定会の資料として、指摘を画面に紐づけて配りたい
- 実装側からのフィージビリティ指摘を、対応漏れなく仕分けたい
- 引き継ぎ時に「この画面で何が議論されたか」を残したい

日々のメンション巡回は `/council-figma`（Slack DM + REST の二経路収集）を使う。
こちらは**ファイル単位の全件棚卸し**が役割。

## 実行手順

### Step 0: 引数の確認

引数から Figma の URL（または file key）を取る。無ければユーザーに聞く。
`--days` 相当の指定（「直近2週間だけ」等）があれば控えておく。

### Step 1: 機械判定で全件を取る（1パス目）

```bash
python3 ~/.claude/skills/figma-comment-map/scripts/figma_comment_map.py \
  "<FigmaのURL>" --me "<自分のFigma handle>" --out "<出力先>" --json-only
```

`--me` は要対応判定の基準。省略時は環境変数 `FIGMA_ME` を見る。
出力される `<ファイル名>_threads.json` には各スレッドの
`n`（スレッド番号）/ `status` / `screen` / `text` / `replies` / `last_activity` が入る。

**ステータスの自動判定ルール**（機械的に決まる部分）

| status | 条件 |
|---|---|
| `done` | Figma 上で解決済み |
| `replied` | 最後に発言したのが自分 → 相手待ち |
| `crit` | 最後が他者で、直近2発言に `@自分` がある |
| `act` | 最後が他者で、返信ゼロ or 末尾が質問・依頼の言い回し |
| `ref` | 上記以外（議論の記録） |

`--stale-days`（既定 21）より古い未返信は一段下げる（`crit`→`act`→`ref`）。
古い未返信を今日の対応リストと同列に並べると、返すべきものが埋もれるため。

### Step 2: 判断を足す（ここがエージェントの仕事）

`threads.json` を読み、**機械判定では決まらない部分**を notes ファイルに書く。

- `note` — そのスレッドが要するに何なのかを**一行**で。画面名・依頼者・未処理の箇所を具体的に書く。
  「議論あり」のような要約禁止。レポート上ではこの一行がコメント本文の上に出て、目次にも並ぶ
- `status` — 機械判定の上書き。よくある補正は次の2つ
  - 実装スコープやリリースを止めているものを `crit` に上げる（メンションが無くても）
  - 既に別スレッドで決着したもの、v1 に反映済みの経緯を `ref` / `done` に下げる
- 内容が読み取れないもの（ピンだけで文脈が分からない等）は `wait` にして、
  何が分からないかを `note` に書く。**推測で埋めない**

```json
{
  "T68": {"status": "crit", "note": "ある要素の設計難易度。実装側から自分に検討依頼"},
  "T44": {"status": "done", "note": "ボタン文言の変更で決着"},
  "T46": {"status": "wait", "note": "「この要素」が何を指すか判別できず"}
}
```

キーは `T<番号>` か comment id。`_` で始まるキーは無視されるのでメモを書いてよい。
**書かなかったスレッドは自動判定のまま出る**ので、全件書く必要はない。

### Step 3: レポートを生成（2パス目）

```bash
python3 ~/.claude/skills/figma-comment-map/scripts/figma_comment_map.py \
  "<FigmaのURL>" --me "<handle>" --out "<出力先>" --notes "<notes.json>" --pdf
```

出力：
- `<ファイル名>_コメント棚卸し_<日付>.html` — スクショにピンを重ねた本体（ピン⇄スレッドが相互リンク）
- `<ファイル名>_コメント棚卸し_<日付>.pdf` — `--pdf` 指定時。返信を展開した印刷版
- `<ファイル名>_threads.json` — 構造化データ

notes ファイルは次回も使えるので、出力先に残して育てる。

### Step 4: ターミナルに要約を出す

生成したファイルのパスと、次を提示する。

1. **要対応の総数**と、そのうち実装・進行を止めているものの内訳
2. **止まっている理由**を1件1行で（誰の指摘か、何が決まっていないか）
3. スクショを省略した範囲があればその旨（ページ全体にピンが打たれている場合など）
4. ステータスは推定であること。共有前に目視すべき箇所を名指しする

## オプション

| オプション | 既定 | 用途 |
|---|---|---|
| `--me HANDLE` | `$FIGMA_ME` | 要対応判定の基準ユーザー |
| `--out DIR` | `.` | 出力先 |
| `--days N` | 全件 | 直近 N 日に動きがあったスレッドだけ |
| `--stale-days N` | 21 | この日数より古い未返信を一段下げる（0 で無効） |
| `--notes FILE` | なし | 一行要約・ステータス上書き |
| `--pdf` | off | PDF も生成（Chrome 系ブラウザが必要） |
| `--max-total-mb N` | 6 | 埋め込む画像の合計上限。超えたら自動で再圧縮 |
| `--max-dim N` | 900 | 画像の長辺 px |
| `--depth N` | 5 | ファイル構造を読む深さ。ピンが深い階層にあるノードに打たれていて画面名が `?` になる場合は上げる |
| `--json-only` | off | レポートを作らず JSON だけ |

## レポートの構造

- **画面のグループ分けは Figma のセクション単位**（最も近い SECTION の名前）。
  検討中の案をセクションで仕切る運用がそのまま検討フェーズの区切りになる。
  セクションが無ければページ名でまとまる
- グループ・画面の並び順は「要対応の多い順」。上から読めば手をつける順になる
- コメントピンは `client_meta.node_offset` を画面の実寸で割った比率で復元しているので、
  Figma 上の位置と一致する

## トークン

環境変数 `FIGMA_TOKEN` → macOS キーチェーン（service 名 `FIGMA_TOKEN`）の順で探す。
未設定なら次を案内する。

```bash
security add-generic-password -s FIGMA_TOKEN -a $USER -w figd_xxxxx
```

必要な権限は **file_comments:read** と **file_content:read**。

## チームに配るとき

スクリプトは Python 3 標準ライブラリだけで動く（画像圧縮は macOS の `sips`、
無ければ Pillow、それも無ければ PNG のまま）。配布時に必要なのは次の3点。

1. `scripts/figma_comment_map.py` と `SKILL.md` をチームの共有リポジトリに置き、
   各自の `~/.claude/skills/` から参照するか、リポジトリ内の `.claude/skills/` に置く
2. 各自が自分のトークンをキーチェーンに登録し、`FIGMA_ME` に自分の handle を入れる
3. スクリプト単体でも動くので、Claude Code を使わないメンバーにも
   `python3 figma_comment_map.py <URL> --me <handle> --pdf` で渡せる

## 取りこぼしを構造的に防ぐ（このスキルの外側）

このスキルは「溜まったものを棚卸しする」道具で、取りこぼし自体は Slack 側の設定で閉じられる。
棚卸しを頼まれたら、あわせて次を提案する。

**1. Slack チャンネルに file を購読させる（推奨・数分）**

対象チャンネルで `/figma subscribe` → 種類で **file** を選び、ファイルを検索 →
配信頻度を **real time / hourly / daily** から選ぶ。file 購読は
**Comments, replies, @mentions** が対象なので、メンションが無いコメントも流れる。

**頻度は real time を推奨**。Figma 側で「10分以内のコメントは1つの Slack メッセージにまとめる」
バッチ処理が入るので、バースト（45分で19件など）でもチャンネルは埋まらない。
hourly / daily は実装を止める質問に気づくのが遅れるため、取りこぼし防止の目的に逆行する。

既に購読があるかは、Slack でそのファイル名を含む Figma bot の**チャンネル**投稿を
検索すれば分かる（DM ではなくチャンネルを見る）。チャンネル内では `/figma list` で一覧できる。

**動作確認**: 自分でメンション無しのコメントを1件打てばよい。
**自分自身のコメントも購読チャンネルには届く**（2026-08-03 実測。公式ドキュメントに記述は無い）。
10分バッチがあるので届くまで最大10分待つ。確認後はテストコメントを消すこと
（Figma 側で削除しても、流れた Slack メッセージは残る）。

購読の通知には**ノードへの直リンク**（`?node-id=...`）が入るので、Slack から該当フレームへ直接飛べる。
DM 通知は `link_redirect` 形式でファイルキーが隠蔽されるため、この点でもチャンネル購読の方が扱いやすい。

**2. 自前で確実にやる場合**

- **Webhook**: `FILE_COMMENT` イベントを file context で作る。file context の上限は
  Professional 150 / Organization 300 / Enterprise 600。受け口（小さな HTTP エンドポイント）が必要
- **定期ポーリング**: このスキルのスクリプトを `--json-only --days 1` で日次実行し、
  前回との差分を Slack に流す。受け口が不要なので webhook より軽い

購読を入れたうえで、月次などにこのスキルで全件突合すると穴が二重に塞がる。

## よくある詰まり

| 症状 | 原因と対処 |
|---|---|
| 画面名が出ず `?` になる | ピンが深い階層のノードに打たれている。`--depth 8` などに上げる |
| スクショが出ない画面がある | 範囲が 20000px 超（ページ全体にピンが打たれた等）。仕様として省略している |
| HTML が重い | `--max-total-mb 3` に下げる。画質を自動で落として収める |
| PDF でスクショが1ページ目にしかない | 仕様。画面と紐づけて追うなら HTML を使う |
| 要対応が多すぎる | `--stale-days` を短くする。または Step 2 で `ref` に下げる |

