From figma-differ
Posts diff results to Slack using persistent frame threads. Each tracked frame gets a permanent parent message; diffs and comments are thread replies. Use when the user runs /figma-differ:notify, or says "post the diff to Slack", "share the Figma diff", "notify the team about design changes", or "send diff to Slack".
How this skill is triggered — by the user, by Claude, or both
Slash command
/figma-differ:notify [<figma-file-url>][<figma-file-url>]This skill is limited to the following tools:
The summary Claude sees in its skill listing — used to decide when to auto-load this skill
- Read `~/.figma-differ/config.json` to get `slack_channel_id`
~/.figma-differ/config.json to get slack_channel_id
slack_channel_id: error — Set slack_channel_id in ~/.figma-differ/config.jsonfileKey from itlatest-diff-all.json under ~/.figma-differ/*/fileKey from the pathRead ~/.figma-differ/<fileKey>/latest-diff-all.json. This is the structured JSON output from bulk-diff.js.
Structure:
{
"total": 10,
"unchanged": 7,
"top": [
{
"id": "2895:40497",
"name": "Login Screen",
"page": "Profile",
"severity": "critical",
"changes": [
{ "type": "added", "count": 5, "details": "..." },
{ "type": "text", "details": "\"Sign In\" → \"Log In\"" },
{ "type": "fill", "details": "header #F85149 → #D29922" }
],
"nodeCount": { "before": 142, "after": 147 }
}
],
"rest": [...],
"comments": {
"new": [{ "author": "Alice", "text": "Button needs variant", "nodeId": "2895:40497" }],
"resolved": [{ "text": "Icon alignment", "resolvedBy": "Bob", "nodeId": "2895:40501" }]
}
}
If file not found: error — No diff result found. Run /figma-differ:diff-all <url> first.
Read ~/.figma-differ/<fileKey>/slack-threads.json. If it doesn't exist, initialize:
{ "channel_id": "<slack_channel_id>", "threads": {} }
Read ~/.figma-differ/<fileKey>/index.json to get:
fileName — the Figma file namepage name (from the frames array)Combine top and rest arrays from the diff JSON. For each frame with changes:
Infer a semantic emoji from the frame name:
:lock: — login, sign in, auth:gear: — settings, preferences, config:bust_in_silhouette: — profile, account, user:inbox_tray: — inbox, notifications, messages:moneybag: — net worth, balance, portfolio, finance:gift: — gift, rewards, offers, promotions:page_facing_up: — statements, documents, history:shield: — security, privacy, verification:house: — home, dashboard, overview:mag: — search, explore, discover:credit_card: — payments, cards, transactions:bar_chart: — analytics, reports, charts:iphone: — default/fallback for any screenBuild the Figma deep-link:
https://www.figma.com/design/<fileKey>/<fileName>?node-id=<nodeId with : replaced by ->
Post parent message:
<emoji> *<Frame Name>* · <<figma-deep-link>|Figma> · _<Page Name>_
Use mcp__claude_ai_Slack__slack_send_message with:
channel_id: from configmessage: the formatted parent messageSave the returned message_ts (from the tool response) to the registry:
"threads": {
"<frameId>": { "ts": "<message_ts>", "name": "<Frame Name>", "page": "<Page Name>" }
}
Build a single thread reply message grouping all changes for this frame. Format:
*Apr 2 — N changes detected*
> <change lines with emojis>
>
> _<before> → <after> nodes_
Change type emoji mapping:
added or removed → 🧩 :jigsaw: — e.g. > :jigsaw: +5 nodes addedtext → ✏️ :pencil2: — e.g. > :pencil2: 2 text changes: "Sign In" → "Log In"fill or color or stroke → 🎨 :art: — e.g. > :art: fill: header #F85149 → #D29922layout or spacing or padding → 📐 :straight_ruler:component or swap → 🔀 :twisted_rightwards_arrows:visibility → 👁️ :eye:bbox or position → 📍 :round_pushpin:baseline or resolved or none → 🤏 :pinching_hand: (matches baseline)Use mcp__claude_ai_Slack__slack_send_message with:
channel_id: from configmessage: the formatted diff replythread_ts: the ts from the registry for this frameFor each new comment in comments.new, find the frame thread by nodeId:
:speech_balloon: *<Author Name>*
> <comment text>
For each resolved comment in comments.resolved, find the frame thread by nodeId:
:speech_balloon: ~"<comment text>"~ — _resolved by <Author>_
Post each as a thread reply using thread_ts from the registry.
If a comment's nodeId doesn't have a thread, skip it (comment is on an untracked frame).
Write the updated slack-threads.json back to ~/.figma-differ/<fileKey>/slack-threads.json:
{
"channel_id": "<slack_channel_id>",
"threads": {
"<frameId>": { "ts": "<message_ts>", "name": "<name>", "page": "<page>" },
...
}
}
Slack notify complete — <fileKey>
Threads: N parent messages (M new, K existing)
Diff replies: X posted
Comment replies: Y posted
Channel: <channel_id>
mcp__claude_ai_Slack__slack_send_message with params: channel_id, message, optional thread_tschat.update or reactions.add API — never reference themApr 2, Mar 15, etc.npx claudepluginhub tokyo-megacorp/figma-differ --plugin figma-differCreates, edits, and optimizes skills for Claude Code, including drafting, evaluating with test prompts, iterating on performance, and improving skill descriptions for better triggering accuracy.