Figma Bridge
Figma 沒有公開的寫入 API。此技能使用一個本地橋接器:透過 HTTP 傳送命名操作, 由 Figma 內的外掛透過 Figma 外掛 API 執行。無需 OAuth,無需 token。
倉庫: https://github.com/iggypcnfsky/figma-bridge — AGENTS.md、docs/ops-reference.md。
前置條件 — 請先檢查所有事項
figma 在 PATH 中,因此永遠不要在檔案系統中搜尋該倉庫:
figma doctor # 一次檢查:倉庫、伺服器、已連接視窗、img-forge + FAL 金鑰
figma clients # 每個已連接 Figma 視窗的 id、file、page
figma rules # 專案限制條件:類型底限、網格、框架尺寸、版本命名
請在設計前閱讀 figma rules。 它載明了不明顯的限制 — 例如「Poppins 20/25 是底限」 — 這些是無論如何閱讀畫布都無法得知的。將 "confirmed": false 視為需要與使用者確認的假設,而 {} 表示「請詢問,不要自行發明」。
如果指令缺失,僅在詢問後使用 node "$(figma where)/server.mjs";不要 find 該倉庫,也不要猜測路徑。
pluginConnected: false→ 停止。請使用者執行Plugins → Development → Figma Bridge在他們想要操作的檔案視窗中。重試沒有幫助。- 來自
/run的503表示相同意思。504 PLUGIN_GONE表示他們關閉了外掛視窗。 409表示有數個 Figma 視窗已連接,但未選取任何一個。選取使用者命名的檔案 (--file <NAME>) 或一個用戶端 id (--client <ID>);永遠不要盲目重試,否則您可能編輯到錯誤的檔案。
循環
- 定位。
./bin/figma status→ 檔案名稱、目前頁面、選取範圍、所有頁面。 - 讀取。
selection 2、node <id> 2、find {"name":"Header","allPages":true}。 永遠不要猜測nodeId— Figma 的 id 看起來像4022:2且無法推導。 - 計劃。 決定父層、尺寸、順序。新節點會放到目前頁面,除非指定了
parentId。 - 寫入。
./bin/figma run '[{...},{...}]'。 - 驗證。
./bin/figma export <id> out/check.png PNG 2並確實檢視圖片。
指令
./bin/figma op '{"op":"status"}'
./bin/figma run '[{"op":"createFrame","name":"Card","width":320,"height":200,"fill":"#0B0B0F",
"props":{"cornerRadius":16,"layoutMode":"VERTICAL","paddingTop":24,"paddingLeft":24,"itemSpacing":12}}]'
./bin/figma run '[{"op":"createText","parentId":"12:34","characters":"Title","fontSize":24,"color":"#FFFFFF"}]'
./bin/figma op '{"op":"varFill","nodeId":"12:34","variableName":"color/bg/surface"}'
./bin/figma export 12:34 out/card.png PNG 2
./bin/figma image 12:34 out/cover.png FILL # 本地圖片檔案 → 填滿(無需雲端上傳)
操作:ping status pages variables styles fonts inventory · selection node find · createFrame createRect createEllipse createText createPage createInstance · update clone reparent remove goto group ungroup select · grids setGrids align distribute effects · applyStyle varFill · export imageFill · exec。
完整參數:docs/ops-reference.md。
值得知道的設計工作捷徑:
- grid 就是 GRID:當使用者說「設定網格」,他們想要方形佈局網格,而不是欄:
{"op":"setGrids","nodeId":"…","grid":true}(預設 40 像素網格、40% 不透明度)或"grid":40。 僅在使用者說欄、12 欄網格或提供間距/邊距值時使用columns/rows。 永遠不要用矩形偽造網格;applyStyle搭配kind:"grid"會套用已儲存的網格樣式。 - 項目行:建立項目後,使用
{"op":"align","nodeIds":[…],"mode":"TOP"}和{"op":"distribute","nodeIds":[…],"axis":"HORIZONTAL","gap":24}。 - 陰影與模糊:
{"op":"effects","nodeId":"…","shadow":{"y":8,"blur":24,"color":"#00000033"}}或{"op":"effects","nodeId":"…","blur":{"type":"BACKGROUND","radius":20}}。 - 漸層:
{"op":"gradient","nodeId":"…","kind":"linear","angle":135,"stops":[[0,"#8B76FF"],[1,"#0E0E12"]]}— 角度 0 是從左到右,90 是從上到下。永遠不要用堆疊的矩形偽造漸層。 - 設計系統:使用
COMPONENTid 的createInstance,然後使用instanceProps處理變體(先讀取名稱) 以及instanceText在不分離的情況下變更文字;使用applyStyle套用樣式。不要 重繪函式庫已提供的內容,也不要為了「修正」文字而分離實例。 - 間距檢查:
{"op":"measure","a":"1:2","b":"1:3"}會傳回每側的間距和中心距離; 用它來取代匯出螢幕截圖以判斷對齊方式。 - 樣式:
saveStyle會依名稱建立或更新text/paint/effect/grid樣式,而applyStyle會套用它。建立 token 一次,套用到所有地方。 - 響應式:
sizing設定每個軸的HUG/FILL/FIXED加上最小/最大值;constraints涵蓋 非自動佈局的子層(STRETCH/MIN/MAX/CENTER/SCALE)。在變更前從node讀取這兩者 — 當屬性不適用時,sizing會傳回skipped以及 Figma 的原因。
圖片
需要製作圖稿?使用同系列的 img-forge CLI 生成
(https://github.com/iggypcnfsky/img-forge),然後放置它 — 生成作業保持在 Figma 外部,
因此 API 金鑰永遠不會進入外掛程式碼,且緩慢的渲染不會阻塞畫布:
cd ../img-forge
./img gen --prompt "abstract gradient cover, purple to black" --preset 16:9@2k --out out/cover.png
./img edit --prompt "make it night with neon accents" --ref out/cover.png # 或編輯現有素材
cd ../figma-bridge
./bin/figma image 12:34 ../img-forge/out/cover.png FILL
FILL 會裁剪以符合節點,FIT 會加上黑邊,TILE 會重複,CROP 會尊重現有的裁切。
要編輯使用者選取的內容,請先匯出它(./bin/figma export <nodeId> out/sel.png PNG 2)並
將該檔案作為 --ref 傳遞。
外掛視窗也有一個供人類使用的 Generate / Edit 面板(模型、尺寸預設、成本、插入)。
不要以程式方式驅動面板 — 使用 CLI;它提供更多功能(遮罩、變體、試跑)。
在該面板中儲存的預設位於 figma-bridge/presets.json。
建立在現有草稿上
「未完成」的草稿仍然編碼了決策:什麼與什麼相鄰、什麼被群組、元素的順序、間距節奏。 在設計前先讀取它,然後保留它。
{"op":"inventory"}— 框架、其尺寸和排版統計資料。{"op":"structure","nodeId":"<frame>"}— 子層按行分組,附帶間距和readingOrder; 這就是作者所選擇的分組。{"op":"node",…,"depth":2}會提供具有更多深度的相同樹狀結構。- 注意模式(重複出現的左邊距、總是位於三欄上方的標題)並保留它。 變更需求所需的內容,其餘保持原樣。
- 回報您所做的變更 — 「將頁尾上移 40 像素」,而不僅僅是「改善佈局」。
永遠不要默默地標準化草稿。如果統一性需要移動使用者放置的內容,請告知並詢問; 一個看起來整齊但失去他們分組的投影片是退步,而不是改進。
規則
- 先讀後寫。 至少兩個呼叫:檢查,然後修改。
- 一個批次 = 一個想法。 一個操作無法參考前一個操作的結果,因此如果您需要
新節點的
id,請分成兩個呼叫。 - 尊重您繼承的排列方式:兄弟順序、鄰近性和分組都是意圖。除非被要求,否則不要 重新編排草稿使其看起來更整齊;如果統一性會移動他們的元素,請先詢問。
- 未經明確指示,永遠不要觸碰現有使用者圖層(
update、remove、reparent)。 為您自己的創作加上前綴:Bridge / …。 - 修改版本應盡可能緊鄰原始版本。 被要求重做投影片/畫面/區塊時:複製它,呼叫
{"op":"placeNear","nodeId":"<new id>","move":true,"gap":80,"name":"Bridge / v2 — <name>"},讓副本 落在第一個空白側邊而不是猜測的座標,並保留原始版本不變。 如果工具回報free: false,詢問應該放在哪裡。僅在使用者明確要求時才在原地取代元素。 goto會變更使用者的檢視畫面 — 僅在要求時。exec是最後的手段。 它確實有效(Figma 的沙箱允許new Function)並繞過所有 參數驗證。僅回傳 JSON 可序列化的值。- 清理測試用的成品,或詢問是否保留它們。
陷阱
- 使用
localhost,永遠不要使用127.0.0.1:外掛清單僅允許http://localhost:3847(devAllowedDomains);Figma 會拒絕 IP。伺服器同時監聽127.0.0.1和::1。 figma.currentPage是該 Figma 視窗中開啟的頁面 — 不是儲存的指標。切換頁籤 會改變您在下一次呼叫中看到的內容。- 位置是相對於父層,而省略
parentId表示 目前頁面。 - 排版問題(哪些字型、大小、數量)只需一個呼叫:
{"op":"fonts"};加上"allPages":true以涵蓋整個檔案。不要自行編寫腳本遍歷框架。 - 投影片總覽也是一次呼叫:
{"op":"inventory"}會回傳每個框架的幾何資訊、minFontSize、字型、網格數量和填滿 — 足以選取「框架 11–19」或找出低於最小尺寸的文字。 - 永遠不要索引參考文件未列出的欄位。
summary為 TEXT 類型載有font、fontSize、lineHeight和letterSpacing;其他所有內容則來自使用真實 API 名稱的exec。混合樣式 是字串"MIXED",因此請使用.get()和後備值進行保護。 - 矩形不能有子層;當文字或圖示必須位於形狀內部時,請使用框架。
- 沒有本地變數 →
variables會回傳collections: [],且varFill會失敗。請先檢查。 - 文字需要字型:
createText會透過loadFontAsync載入它;如果該字型家族遺失,請使用Inter。 export的上限為 8 MB — 降低scale而不是重試。- 讀取非目前頁面的子層需要
loadAllPagesAsync;橋接器會自動重試一次, 但建議使用find並加上allPages: true。 - 編輯外掛檔案(
code.js、ui.html)後,使用者必須重新執行外掛;對manifest.json的變更需要重新匯入。