Figma Agent 与一键发布:设计令牌的 npm 推送之路

19

一个月前,我决定我们的设计令牌流水线应该自己运行。我让Claude Code重写了我的令牌CLI,让代理能驱动它,接线Figma代理,一切都正常工作了。

现在我一个都不用了。我改成点一个按钮。

无聊的仪式

在吉特巴特勒我们的设计代币不存在于应用仓库中。它们存在于一个独立的包中,@gitbutler/design-core,发布到npm。应用像使用其他依赖一样,按版本消耗令牌。

这意味着每个令牌都会变化,甚至如此一色必须成为真正的NPM发布。

为什么要这样工作,而不是直接把令牌留在 monorepo 里?因为令牌会为多个代码库提供信息:桌面应用、网站,或者我们接下来构建的任何代码。

版本号是唯一能让它们保持同步的东西。它还让每一次变更都成为有意且可审查的发布:有差异、周期的提升,消费者可以随时升级。重命名的变量变成了带有警示标签的主流版本明天的版本也不足为奇。

所有这些安全性的代价正是本文的问题:哪怕只有一种颜色,也必须完整发布流程。

很长一段时间里,一个发布的版本通常是这样的:

  • 打开我的托肯斯桥Figma 中的插件
  • 选择导出设置
  • 下载.zip
  • 拉开拉链
  • 把JSON复制到design-core里
  • 跑露台将 JSON 转换为 CSS
  • 提交
  • 推
  • 给一个版本打标签(0.x.x?0.x.x+1?想想,帕维尔,想想)
  • 登录 npm 并发布
  • 十步。全手动。

    我多年前写了这个插件,那时还没人谈论代理,仪式感从未改变。它不难,只是无聊。而那些无聊且永不改变的事情,正是你应该自动化的。

    “你能运行我的插件吗?”——不行。

    于是我打开了Figma代理,问:你能运行我的插件并导出令牌吗?我知道它可能做不到,但我想看看它会说什么。

    不行。Figma代理不能操作插件。不能点击按钮,不能代表你驱动UI。代理只能接收API。但代理可以运行CLI工具。

    好吧,行。那是通过REST API来控制变量吗?也不是,除非你在企业计划.官方远程读取变量的方法隐藏在Figma的付费墙后面。

    需要说明的是,Tokens Brücke 也作为 CLI 发布,插件和 CLI 都包含可以去了解REST API。这条路径一直存在,适合有计划的人。所以付费墙并不新鲜。

    有趣的是:找到变通方法,让所有人免费使用。

    变通办法:快照输入,令牌输出

    代理人可以通过插件API从内部读取文件。只是无法在文件上运行插件的变换逻辑。

    还记得 CLI 吗?它唯一能进入 Figma 的入口就是那个付费的 REST API。于是我在 VS Code 里打开插件仓库,问 Claude:它也能接受 raw 文件吗快照变量而不是调用API?

    Claude 重写了它。现在你可以这样做:

    # agent dumps variables via Plugin API → snapshot.json
    npx tokens-bruecke --input snapshot.json --output tokens.json
    

    没有企业套餐。没有访问令牌。我也是DTCGJSON(Design Tokens 社区组格式)作为插件。Claude 还添加了一个init入职(四个问题,保存配置,永不再问)以及技能,代理世界对已保存指令集的称呼。

    你只需描述一次过程(倾出快照,运行CLI,打开PR),之后每当我说“导出令牌”时,代理就会重放它。

    有趣的细节:这项工作需要二代理,Claude在重写CLI和Figma代理对真实文件进行测试。我不知道怎么连接它们。所以我自己连接了它们。

    复制Claude的回答,粘贴到Figma代理中。复制回复,粘贴回来。

    两名特工。一块人类夹板。这是我迄今为止最高级的职位。

    GitHub 那一半

    流水线的另一半转入了GitHub Actions。我描述了规则,Claude 编写了 YAML。手写动作主要是查找下个月你会忘记的语法,而这正是值得交接的部分。

    代理并不知道自己的连接器存在。虽然它告诉我“没有 git 凭证”,但 GitHub 连接器却运行在+同一个聊天窗口的菜单。

    推送的部分已经涵盖了。但 PR 进入仓库只是工作的一部分。总得有人重建 CSS,选一个版本,然后发布。那个人就成了两个 GitHub Actions 的工作流程,生活在 design-core:

    tokens-pr.yml——当PR触及令牌JSON时:用Terrazzo重建CSS,调配自定义属性,选择版本提升(自动补丁或次要;主要不推断,需要显式标签,因为移除CSS变量会破坏所有消费者),撞击,并在PR上注释完整的标记差异。

    release.yml——合并时:发布到NPM,标记,创建发布,编写变更日志。

    这是我最喜欢的整个项目的今天才知道的:NPM可信出版.我以为我会永远每隔几个月轮换一次 npm 访问令牌。结果发现你只需要把 GitHub 仓库连接到 npm 包一次,Actions 通过 OIDC 发布。

    没有令牌。

    六分钟

    所以:完全自动化实现了。我说“导出令牌”,几分钟后GitHub上就出现了一个PR,带有版本提升和差异。

    稍等一下。具体来说:六分钟.每一次跑步。

    我以为我的技能让特工过度思考,所以我调整了它。“别想。直接跑剧本。”还是六分钟。我让它更激进:零问题,零停顿,提取→变形→推动→公关→完成。

    还是六分钟。

    为什么Figma代理处理文件很慢

    代理没有手。它完全存在于文本中:它以文本形式发送工具调用,并以文本形式返回结果。每个代理都是如此。让它变成牢笼的是平台交付的工具。

    Figma代理的GitHub连接器接收文件目录作为论点,它的沙盒没有git,也没有直接网络。所以推送semantic.tokens.json,三个文件中最大的一个,54 KB,代理必须cat文件进入自身上下文,然后每重输入一个字节进入API调用。

    而且它的输出流被限制在几十KB左右,所以文件根本装不下:“语义文件太大,无法做stdout。”

    这就像通过电话大声朗读一本书,然后有人写下来,然后复印一本书。这对一段话来说是有效的。但写一本书却失败了。

    公平地说:这并不是“AI代理处理不了文件”。Claude代码放在仓库里只是运行git push,字节从磁盘直接传到GitHub,而从未进入聊天。

    Figma代理并不更笨;它被困住了。

    那为什么不直接用Claude Code运行整个流程呢?因为这个笼子是双向的。Claude Code可以整天推送文件,但它不在Figma文件里。我面前的两个代理中,唯一能推送的阅读不能用力,以及那个能做到的用力不能阅读.

    反转:老纽扣赢了

    然后我想起一件尴尬的事。

    我的插件有一个“推送到服务器”按钮,带有GitHub PR目标多年来.我是在这一切发生之前自己做的。而插件正是两个代理无法成为的演员:它存在里面文件,所以它可以读取所有变量,并且拥有自己的网络访问权限,可以推送而无需在任何聊天中挤出字节。

    一键:插件读取令牌,推送JSON,PR显示,Actions完成所有其他操作。

    总时间:秒。

    那我为什么从没用过自己的按钮呢?因为它单独做的只有一半的工作。它只推入JSON并打开PR,然后重建CSS、选择版本、发布和标记仍然得我自己负责。

    缺少的一半是GitHub Actions,而我从来不会写好Actions,无法信任它们发布。这就是Claude给我的部分。一旦有了工作流程,一个只需按下JSON的按钮就成了整个任务。

    所以,在给CLI添加技能、引导和快照模式,并作为专业人类剪贴板的经历后,最成功的设置是:

  • 点击插件中的“推送到服务器”。CI重建CSS,选择版本,注释差异。
  • 阅读差异。合并。CI负责发布、标记、编写变更日志。
  • 十步变成了两点。而且这些步骤都不涉及大型语言模型。

    以下是整个过程的单一视频:

    有没有经纪人跳过了剪贴板?

    Claude 代码配合 Figma 的开发模式 MCP 确实能看到什么东西.我让它读取了我们文件中的变量并与 design-core 进行对比:大约一半的变量回来了,只有所选节点恰好使用的变量,没有别名、模式和描述。

    解析了颜色,不是标记。选择整个标记页面则显示相同情况:--bg-2返回为#f2f2f2,而不是作为别名gray-90,暗模式值也没有。就是这样getvariabledefs这个工具就是设计来实现(它解析选择用到的部分),所以它不是用来导出完整导出的工具,而不是坏掉的工具。

    同一MCP服务器还有一个usefigma运行插件API代码的工具,原则上可以将所有带有模式和别名的集合直接转储到一个具有git.我还没试过那条路。

    还有一种方法Figma-控制台-MCP:一个本地MCP服务器和一个你导入到Figma的开发插件。插件通过插件API读取变量,然后通过WebSocket传递给你机器上的Node进程,Claude Code有真实的磁盘和真实的git push.和我的快照模式一样,只是没有人工剪贴板。

    注意这两个都缺少谁:Figma代理。它无法连接MCP服务器,所以每个桥接器只对活着的代理有效外面Figma。笼子是平台选择,不是自然法则。

    但这些都不改变数学。桥接依然会把LLM放在任务中间,按钮几秒钟内就能完成。

    我保留的东西

    LLM 是一台假装是人类的机器,它拥有人类的配置文件。它擅长人类部分:阅读混乱的代码库,发现接缝,找出该改动的地方。它在机器部分做得不好:快速地做同样的事情上百次,却不假思索。

    所以用它的方式就像对待聪明的同事一样,而不是用 CPU 的方式。Claude Code 重写了我的 CLI 和 GitHub Actions。但流水线本身只是脚本,脚本不需要思考。

    CI 会碰撞、发布、记录。剩下的人类步骤是那些真正需要人工的步骤:读取差异并决定是否发布。

    如果已有工具(如CLI、按钮、工作流程),就把工具交给AI,而不是让它手动重做。代理的速度取决于它最差的工具。除非平台允许工具使用文件路径不要只写文件内容,而是让脚本移动字节。

    代理应该只说“推送”。

    我无论如何都会保留的绕道之一是快照模式。通过插件API快照读取令牌而不是企业REST API,意味着所有人都能用同样的令牌,没有付费墙。

    最后一件有趣的事:我发布了带有AI风格的版本后,插件下载量从每周400跃升至1300。我很想告诉你,这都是因为这些出色的代理工具。

    附言:我把这篇文章粘贴到Figma代理里,问我哪里错了。它没发现什么。我不会多想,但它确实比我用2000字表达得更清楚:

    “我擅长写脚本和CI配置;但我对确定性流水线来说运行得很糟糕。”
    参与讨论