skills/track/SKILL.md
Subscribe to a Figma file for automatic syncing and semantic search. Adds the file to tracked.json, runs initial index + snapshot-all + frame.md generation, and initializes the QMD search collection. Use when the user runs /figma-differ:track or says "track this Figma file", "subscribe to Figma", "watch this design file", or "add to tracked files".
npx skillsauth add tokyo-megacorp/figma-differ trackInstall this skill globally with one command. Works with Claude Code, Cursor, and Windsurf.
3 of 9 scanners reported clean
Some scanners were skipped, did not run, or reported a non-clean status. Review each row below.
Extract fileKey from the Figma URL (https://www.figma.com/design/<fileKey>/...).
Parse flags from $ARGUMENTS:
--children — save direct FRAME/COMPONENT/SECTION children of the root node (depth=1)--children=2 — also save grandchildren (depth=2); the save tool handles depth=1 per call, so invoke again on each childVerify a Figma token is loadable: bash $CLAUDE_PLUGIN_ROOT/scripts/auth.sh status (if it fails, tell the user to run bash $CLAUDE_PLUGIN_ROOT/scripts/auth.sh set and stop).
Create tasks per phase. Dispatch haiku subagents — raw output stays forked.
TaskCreate("Register tracked file", activeForm: "Adding <fileName> to tracked files...")
TaskCreate("Index all frames", activeForm: "Cataloging frames and sections...")
TaskCreate("Snapshot all frames", activeForm: "Fetching node.json + PNGs for <N> frames...")
TaskCreate("Extract screen flows", activeForm: "Mapping connector lines and transitions...")
TaskCreate("Generate frame docs", activeForm: "Extracting text, colors, buttons, layout...")
TaskCreate("Enable semantic search", activeForm: "Indexing frames for semantic search...")
Task lifecycle:
TaskUpdate(taskId, status: "in_progress")Agent(model: "haiku") — agent reports only counts, never raw outputTaskUpdate(taskId, status: "completed")~/.figma-differ/)Path: ~/.figma-differ/tracked.json
If it doesn't exist, initialize:
{ "files": {} }
If the fileKey is already tracked, inform the user and ask if they want to re-sync. If yes, continue. If no, stop.
{
"files": {
"<fileKey>": {
"url": "<full figma url>",
"fileName": "",
"addedAt": "<ISO 8601 timestamp>",
"lastSynced": null
}
}
}
Write the updated tracked.json.
Invoke /figma-differ:index <url> to catalog all frames.
After indexing, read ~/.figma-differ/<fileKey>/index.json to get the fileName and frame count. Update tracked.json with the fileName.
Invoke /figma-differ:snapshot-all <url> to baseline all frames.
The index step fetched the file tree to a temp file. If that file still exists, extract flow connections. Otherwise fetch a fresh tree:
TREE_FILE="/tmp/figma-tree-<fileKey>-$$.json"
# Re-use tree from index/snapshot-all if available, otherwise fetch
if [[ ! -f "$TREE_FILE" ]]; then
bash $CLAUDE_PLUGIN_ROOT/scripts/figma-api.sh fetch_file_tree <fileKey> > "$TREE_FILE"
fi
node $CLAUDE_PLUGIN_ROOT/scripts/extract-flows.js <fileKey> "$TREE_FILE"
rm -f "$TREE_FILE"
node $CLAUDE_PLUGIN_ROOT/scripts/generate-frame-md.js <fileKey>
source $CLAUDE_PLUGIN_ROOT/scripts/lib/qmd.sh
qmd_reindex
If QMD is not installed, warn the user but don't fail — tracking and snapshots still work without search.
--children)If --children or --children=2 was passed, use whichever path is available:
Preferred — Figma MCP (get_metadata):
get_metadata returns a sparse XML tree with IDs and names — no heavy JSON download needed.
get_metadata(fileKey, nodeId) on the root nodeget_design_context(fileKey, childId) → figma-differ save--children=2: repeat step 1–3 for each childFallback — REST API (save_children: true):
Use when Figma MCP is unavailable. Pass save_children: true on the root figma-differ save call; the tool parses the already-fetched node JSON and persists matching children automatically.
For depth=2 via REST: call figma-differ save with save_children: true for each child returned by the first call.
Report child count in the final summary.
Set lastSynced to the current ISO 8601 timestamp.
Tracked: <fileName> (<fileKey>)
Frames indexed: N
Snapshots stored: M
Frame docs generated: G
Children saved: K (--children) ← only if --children was used
QMD search: ready (M documents) | unavailable (qmd not installed)
Run /figma-differ:search "query" to find frames.
Run /figma-differ:sync to refresh later.
Run /figma-differ:diff-all <url> to check for changes.
documentation
Refresh snapshots and search index for tracked Figma files. Fetches current state from Figma, generates frame.md documents, and updates the QMD search index. Use when the user runs /figma-differ:sync or says "sync Figma", "refresh snapshots", "update the Figma index", or "re-sync tracked files".
tools
Takes a snapshot of a Figma node — fetches its JSON structure and PNG screenshot and stores both to ~/.figma-differ/ for later diffing. Use when the user runs /figma-differ:snapshot with a Figma URL, or says "snapshot this Figma frame", "save a Figma baseline", or "take a Figma snapshot".
development
Bulk snapshots every frame in a Figma file — fetches all node JSONs, exports PNGs, and stores comments. Uses a single API call for the tree and batched image exports. Use when the user runs /figma-differ:snapshot-all with a Figma file URL, or says "snapshot all frames", "bulk snapshot", "baseline the whole file", or "snapshot everything in this Figma file".
content-media
Semantic search across all tracked Figma frames using QMD hybrid search. Finds frames by content, component names, text strings, or natural language queries like "the login screen" or "frames with portfolio charts". Use when the user runs /figma-differ:search or says "find the Figma frame for", "which frame has", "search Figma frames", or "find frames with".