Openclaw Figma Plugin Writer
自动生成和更新 Figma 插件的 code.js 以创建和修改设计元素,用户更新代码后需手动运行插件执行。
MIT-0 · Free to use, modify, and redistribute. No attribution required.
⭐ 0 · 16 · 0 current installs · 0 all-time installs
byZoe Addamssance@zerozlw
MIT-0
Security Scan
OpenClaw
Benign
high confidencePurpose & Capability
Name/description state the skill will generate/update a Figma plugin's code.js to automate design tasks. The skill requests no credentials, no binaries, and includes only examples and documentation — all of which are appropriate and expected for a local file-writing Figma plugin generator.
Instruction Scope
The SKILL.md explicitly instructs the agent to update the user's plugin directory (write/overwrite code.js). Modifying a user-specified local path is consistent with the stated purpose but is a potentially sensitive filesystem operation: the agent will need write access and will be able to replace plugin code. There are no instructions to read unrelated system files, access environment secrets, call external endpoints, or exfiltrate data.
Install Mechanism
No install spec is provided (instruction-only). Nothing is downloaded or installed by the skill itself, which minimizes installation risk.
Credentials
The skill declares no required environment variables, credentials, or config paths. The SKILL.md asks the user to provide a plugin directory path (via conversation or TOOLS.md) — this is reasonable and proportional for writing code.js.
Persistence & Privilege
Flags show always:false and model invocation not disabled (normal). The skill does not request permanent presence or elevated system privileges and does not attempt to modify other skills or global agent settings.
Assessment
This skill will write or overwrite code.js inside a Figma plugin folder you point it to — that is expected for its purpose but can change files on your disk. Before running it: (1) provide a correct plugin directory path and keep a backup copy of your existing plugin/code.js; (2) review the generated code.js contents before running the plugin in Figma; (3) consider testing in a disposable/new plugin project rather than a production plugin; (4) verify manifest.json (networkAccess, documentAccess) and that you run the plugin manually in Figma as instructed. If you want a lower-risk workflow, ask the agent to produce the code content in the chat for you to paste manually rather than letting it write the file directly.Like a lobster shell, security has layers — review code before you run it.
Current versionv0.1.0
Download ziplatest
License
MIT-0
Free to use, modify, and redistribute. No attribution required.
SKILL.md
SKILL.md — Figma Plugin Writer
概述
通过编写 Figma 插件代码,实现对 Figma 文件的自动化设计。每次更新 code.js 后通知用户触发插件执行。
使用前配置
用户需要告诉 agent 以下信息(在对话中或通过 TOOLS.md):
- 插件目录路径 — Figma 插件所在文件夹(含 code.js 和 manifest.json)
- 代码文件 — 通常是
code.js - 目标 Figma 文件 — 可选,用于上下文说明
示例配置(放入 agent 的 TOOLS.md):
## Figma Plugin Writer
**插件目录:** ~/Desktop/my-figma-plugin/
**代码文件:** code.js
工作流程
- 接收需求 — 用户描述要设计的内容
- 编写插件代码 — 更新
code.js,包含要绘制的设计元素 - 通知用户 — 告诉用户"代码已更新,请运行插件:Plugins → Development → 插件名"
- 等待反馈 — 用户运行后反馈效果,根据反馈迭代
Figma Plugin API 参考
字体加载(必须在创建文字前执行)
await figma.loadFontAsync({ family: "Inter", style: "Regular" });
await figma.loadFontAsync({ family: "Inter", style: "Medium" });
await figma.loadFontAsync({ family: "Inter", style: "Semi Bold" });
await figma.loadFontAsync({ family: "Inter", style: "Bold" });
创建 Frame(画框/容器)
var frame = figma.createFrame();
frame.name = "MyFrame";
frame.resize(width, height);
frame.cornerRadius = 12;
frame.fills = [{ type: "SOLID", color: { r: 1, g: 1, b: 1 } }];
frame.x = 0;
frame.y = 0;
创建文字
var text = figma.createText();
text.characters = "Hello World";
text.fontSize = 16;
text.fontName = { family: "Inter", style: "Regular" };
text.fills = [{ type: "SOLID", color: { r: 0, g: 0, b: 0 } }];
创建矩形
var rect = figma.createRectangle();
rect.resize(100, 50);
rect.fills = [{ type: "SOLID", color: { r: 0.9, g: 0.2, b: 0.2 } }];
rect.cornerRadius = 8;
节点嵌套
frame.appendChild(text); // text 变成 frame 的子节点
parentPage.appendChild(frame); // frame 放到页面上
阴影效果
frame.effects = [{
type: "DROP_SHADOW",
color: { r: 0, g: 0, b: 0, a: 0.1 },
offset: { x: 0, y: 4 },
radius: 12,
spread: 0,
visible: true,
blendMode: "NORMAL",
}];
描边
frame.strokes = [{ type: "SOLID", color: { r: 0.8, g: 0.8, b: 0.8 } }];
frame.strokeWeight = 1;
文字对齐
text.textAlignHorizontal = "CENTER"; // LEFT | CENTER | RIGHT | JUSTIFIED
text.textAlignVertical = "CENTER"; // TOP | CENTER | BOTTOM
自动布局(Frame 内)
frame.layoutMode = "VERTICAL"; // 或 "HORIZONTAL"
frame.primaryAxisAlignItems = "CENTER"; // MIN | CENTER | MAX | SPACE_BETWEEN
frame.counterAxisAlignItems = "CENTER";
frame.paddingTop = 16;
frame.paddingBottom = 16;
frame.paddingLeft = 16;
frame.paddingRight = 16;
frame.itemSpacing = 8;
切换页面
// dynamic-page 模式下必须用异步方法
var pages = figma.root.children;
var targetPage = pages[pages.length - 1];
await figma.setCurrentPageAsync(targetPage);
清空页面内容
var old = targetPage.children.slice();
for (var i = 0; i < old.length; i++) {
old[i].remove();
}
视口操作
figma.viewport.scrollAndZoomIntoView([frame]);
通知
figma.notify("Done!", { timeout: 3000 });
figma.notify("ERROR: " + e.message, { timeout: 10000 });
获取页面信息
var pages = figma.root.children;
var count = pages.length;
var pageName = pages[0].name;
代码模板
async function main() {
try {
// 1. 加载字体
await figma.loadFontAsync({ family: "Inter", style: "Regular" });
await figma.loadFontAsync({ family: "Inter", style: "Bold" });
// 2. 获取目标页面
var pages = figma.root.children;
var target = pages[pages.length - 1];
await figma.setCurrentPageAsync(target);
// 3. 清空旧内容
var old = target.children.slice();
for (var i = 0; i < old.length; i++) old[i].remove();
// 4. 创建设计...
var frame = figma.createFrame();
frame.name = "Screen";
frame.resize(375, 812);
frame.fills = [{ type: "SOLID", color: { r: 1, g: 1, b: 1 } }];
frame.x = 0;
frame.y = 0;
target.appendChild(frame);
// 5. 完成
figma.viewport.scrollAndZoomIntoView([frame]);
figma.notify("Design complete!", { timeout: 3000 });
} catch (e) {
figma.notify("ERROR: " + e.message, { timeout: 10000 });
}
}
main();
重要踩坑记录
documentAccess: "dynamic-page" 模式
manifest.json 中如果有 "documentAccess": "dynamic-page":
- ❌
figma.currentPage = page→ ✅await figma.setCurrentPageAsync(page) - ❌
figma.getNodeById()→ ✅await figma.getNodeByIdAsync() - ❌
figma.closePlugin()→ ✅figma.closePluginAsync()
容错策略
- 所有代码必须包在
try-catch中 - 错误时用
figma.notify("ERROR: " + e.message, { timeout: 10000 })显示 - 不要在文字中使用 emoji(字体可能不支持该 glyph)
- 不要自动调用
figma.closePlugin()(让用户手动关闭)
免费用户限制
- 最多 3 个 Pages,不要创建新 Page
- 在现有 Page 内操作(清空后重建)
字体说明
- 默认使用 Inter(Figma 内置字体)
- 支持的样式:"Regular"、"Medium"、"Semi Bold"、"Bold"
- 如需其他字体,用户需先在 Figma 中安装
- 颜色用
{ r, g, b }格式,值域 0-1
迭代模式
每次设计迭代时:
- 清空目标 Page 内的旧元素:
page.children.slice().forEach(c => c.remove()) - 重新创建新设计
- 通知用户重新运行插件
Files
6 totalSelect a file
Select a file to preview.
Comments
Loading comments…
