content(ai-assistant-figma): callout и распределение медиа

This commit is contained in:
root committed 2026-09-26 19:48:39 +02:00
1 parent a77033e71f
commit 03a8e73ea6
4 files changed
+296 -242

No files matched your search

+74 -61
View File
@@ -431,81 +431,81 @@
<p class="section__prose">
Я хотел убрать ручной перенос кода и запускать скрипты прямо из Figma. Плагин должен был связать Cursor с Figma, дать возможность повторно запускать уже созданные сценарии и быстро копировать для LLM контекст выбранного объекта или страницы.
</p>
<h2 id="solution">Решение</h2>
<p class="section__prose">
Локальный сервер и WebSocket связали Cursor с плагином. Когда скрипт готов, я открываю плагин и нажимаю «Выполнить». Код автоматически передаётся в Figma. Каталог сохраняет сценарии для повторного запуска без Cursor. Плагин не ограничен одной операцией: я могу добавлять скрипты под разные задачи. И всё же запускал их чаще, чем создавал новые.
</p>
<p class="section__prose">
Чтобы LLM точнее понимала макет, плагин умеет копировать информацию о выбранной ноде или целой странице. Логи выполнения мог читать LLM-бот в Cursor. Если проблема была в логике, я разбивал скрипт на небольшие шаги и проверял их по очереди. Сначала тестировал скрипт на отдельном файле. Когда всё работало, пробовал его в рабочем макете.
</p>
<aside class="case-callout" data-callout>
<span class="case-callout__emoji case-callout__emoji--pulse" aria-hidden="true">💡</span>
<div class="case-callout__content">
<p>Я мог добавлять в каталог скрипты под разные задачи и запускать их прямо в Figma.</p>
</div>
</aside>
<figure class="case-media case-media--real">
<img
src="data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7"
alt="Список скриптов AI-ассистента"
alt="Каталог пользовательских скриптов плагина"
data-src="../../assets/ai-assistant-figma/Scripts%20List.webp"
loading="lazy"
decoding="async"
data-image-viewer
/>
<figcaption>Список доступных скриптов ассистента.</figcaption>
<figcaption>Каталог сценариев с поиском, сортировкой и быстрым запуском.</figcaption>
</figure>
<h2 id="solution">Решение</h2>
<p class="section__prose">
Локальный сервер и WebSocket связали Cursor с плагином. Когда скрипт готов, я открываю плагин и нажимаю «Выполнить». Код автоматически передаётся в Figma.
</p>
<figure class="case-media case-media--real">
<img
src="data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7"
alt="Редактор скриптов AI-ассистента"
alt="Редактор скрипта в плагине Figma"
data-src="../../assets/ai-assistant-figma/Script%20Edit.webp"
loading="lazy"
decoding="async"
data-image-viewer
/>
<figcaption>Редактор скрипта для запуска в Figma.</figcaption>
<figcaption>Экран скрипта перед запуском в Figma.</figcaption>
</figure>
<p class="section__prose">
Сохранённые сценарии можно запускать из каталога и без Cursor. Я использовал готовые скрипты чаще, чем создавал новые.
</p>
<figure class="case-media case-media--real">
<img
src="data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7"
alt="Лог выполнения скрипта AI-ассистента"
data-src="../../assets/ai-assistant-figma/Script%20Edit%20Log%20View.webp"
loading="lazy"
decoding="async"
data-image-viewer
/>
<figcaption>Представление лога выполнения скрипта.</figcaption>
</figure>
<figure class="case-media case-media--real">
<img
src="data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7"
alt="Индикатор работы скрипта AI-ассистента"
data-src="../../assets/ai-assistant-figma/Script%20is%20Working.webp"
loading="lazy"
decoding="async"
data-image-viewer
/>
<figcaption>Индикатор активного выполнения скрипта.</figcaption>
</figure>
<figure class="case-media case-media--real">
<img
src="data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7"
alt="Live Mode AI-ассистента"
data-src="../../assets/ai-assistant-figma/Live%20Mode.webp"
loading="lazy"
decoding="async"
data-image-viewer
/>
<figcaption>Live Mode: интерактивный режим ассистента.</figcaption>
</figure>
<figure class="case-media case-media--real">
<img
src="data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7"
alt="Меню More AI-ассистента"
alt="Меню дополнительных действий со скриптом"
data-src="../../assets/ai-assistant-figma/Menu%20More.webp"
loading="lazy"
decoding="async"
data-image-viewer
/>
<figcaption>Дополнительное меню (More) с расширенными действиями.</figcaption>
<figcaption>Меню дополнительных действий со скриптом.</figcaption>
</figure>
<p class="section__prose">
Чтобы LLM точнее понимала макет, плагин копирует информацию о выбранной ноде или целой странице. Эти данные я использовал в диалоге с моделью.
</p>
<figure class="case-media case-media--real">
<img
src="data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7"
alt="Панель плагина с переключателем Live"
data-src="../../assets/ai-assistant-figma/Live%20Mode.webp"
loading="lazy"
decoding="async"
data-image-viewer
/>
<figcaption>Панель управления скриптом с переключателем Live.</figcaption>
</figure>
<p class="section__prose">
Логи выполнения мог читать LLM-бот в Cursor. Если дело было не в ошибке, а в логике скрипта, я разбивал его на небольшие шаги и запускал их по очереди. Сначала проверял сценарий на отдельном файле, а если всё работало, пробовал в рабочем макете.
</p>
<figure class="case-media case-media--real">
<img
src="data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7"
alt="Редактор скрипта с панелью логов"
data-src="../../assets/ai-assistant-figma/Script%20Edit%20Log%20View.webp"
loading="lazy"
decoding="async"
data-image-viewer
/>
<figcaption>Редактор и панель логов выполнения.</figcaption>
</figure>
<figure class="case-media case-media--real">
<div class="case-video-shell">
<video controls preload="metadata" playsinline poster="../../assets/ai-assistant-figma/video/20250904-1414-49.4157894.webp" data-case-video-player style="display: block; width: 100%; height: auto; margin: 0">
@@ -514,9 +514,33 @@
Ваш браузер не поддерживает видео.
</video>
</div>
<figcaption>Демонстрация работы AI-ассистента в Figma.</figcaption>
<figcaption>Доработка скрипта в Cursor и проверка результата в Figma.</figcaption>
</figure>
<h2 id="result">Результат</h2>
<aside class="case-callout" data-callout>
<span class="case-callout__emoji case-callout__emoji--pulse" aria-hidden="true">✅</span>
<div class="case-callout__content">
<p>По моей оценке, на задачу вручную уходило от 1 до 30 минут. Запустить сценарий теперь можно было одним нажатием.</p>
</div>
</aside>
<figure class="case-media case-media--real">
<img
src="data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7"
alt="Индикатор выполнения скрипта"
data-src="../../assets/ai-assistant-figma/Script%20is%20Working.webp"
loading="lazy"
decoding="async"
data-image-viewer
/>
<figcaption>Индикатор активного выполнения скрипта.</figcaption>
</figure>
<p class="section__prose">
Высвободившееся время позволяло браться за более сложные рабочие сценарии. В рабочих файлах я часто запускал скрипт, который сводил векторные иконки через flatten для корректного отображения в продакшене. Другой превращал фрейм в компонент, создавал его инстанс и переносил мастер-компонент в заданное место на странице компонентов. Скрипты также обновляли цветовые токены после ручных изменений и помогали собрать файл дизайн-системы с множеством страниц.
</p>
<p class="section__prose">
Были и другие задачи: добавить варианты компонентов, сохранить набор токенов из JSON в текстовом слое или собрать прототип с переходами по клавиатуре. Я автоматизировал и подсветку кода в макете, чтобы показать идею и подобрать цвета синтаксиса. Вручную я бы за это не взялся.
</p>
<figure class="case-media case-media--real">
<div class="case-video-shell">
<video controls preload="metadata" playsinline poster="../../assets/ai-assistant-figma/video/20250913-0936-57.5977819.webp" data-case-video-player style="display: block; width: 100%; height: auto; margin: 0">
@@ -525,19 +549,8 @@
Ваш браузер не поддерживает видео.
</video>
</div>
<figcaption>Ещё один пример работы AI-ассистента в Figma.</figcaption>
<figcaption>Сборка формы из компонентов дизайн-системы по референсу с помощью скрипта.</figcaption>
</figure>
<h2 id="result">Результат</h2>
<p class="section__prose">
В зависимости от скрипта задача, которая раньше занимала от 1 до 30 минут, теперь выполнялась одним нажатием. Это моя оценка, отдельную статистику я не собирал. Высвободившееся время позволяло браться за более сложные рабочие сценарии.
</p>
<p class="section__prose">
В рабочих файлах я часто запускал скрипт, который сводил векторные иконки через flatten для корректного отображения в продакшене. Другой превращал фрейм в компонент, создавал его инстанс и переносил мастер-компонент в заданное место на странице компонентов. Скрипты также обновляли цветовые токены после ручных изменений и помогали собрать файл дизайн-системы с множеством страниц.
</p>
<p class="section__prose">
Были и другие задачи: добавить варианты компонентов, сохранить набор токенов из JSON в текстовом слое или собрать прототип с переходами по клавиатуре. Я автоматизировал и подсветку кода в макете, чтобы показать идею и подобрать цвета синтаксиса. Вручную я бы за это не взялся.
</p>
<p class="section__prose">
За время работы я лучше разобрался в Figma Plugin API. Теперь при планировании заранее замечаю, какие действия можно скриптовать, чтобы не тратить время на повторяющиеся операции.
</p>
+74 -60
View File
@@ -431,79 +431,80 @@
<p class="section__prose">
I wanted to remove the manual code handoff and run scripts directly in Figma. The plugin had to connect Cursor and Figma, let me reuse existing scripts, and make it easy to copy context about a selected node or an entire page for the LLM.
</p>
<h2 id="solution">Solution</h2>
<p class="section__prose">
A local server and WebSocket connected Cursor to the plugin. Once a script was ready, I opened the plugin and clicked Run. The code was sent to Figma automatically. The catalog saved scripts for reuse without Cursor. The plugin was not limited to one operation: I could add scripts for different tasks. Still, I ran them more often than I created new ones.
</p>
<p class="section__prose">
The plugin can copy details about a selected node or an entire page so the LLM can understand the design more accurately. The execution log was available to the LLM in Cursor. When a problem was about the script's logic, I broke it into small steps and ran them one by one. I tested scripts in a separate Figma file first, then tried them in a working file if everything behaved as expected.
</p>
<aside class="case-callout" data-callout>
<span class="case-callout__emoji case-callout__emoji--pulse" aria-hidden="true">💡</span>
<div class="case-callout__content">
<p>I could add scripts for different tasks to the catalog and run them directly in Figma.</p>
</div>
</aside>
<figure class="case-media case-media--real">
<img
src="data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7"
alt="AI assistant script list"
alt="Catalog of custom plugin scripts"
data-src="../../../assets/ai-assistant-figma/Scripts%20List.webp"
loading="lazy"
decoding="async"
data-image-viewer
/>
<figcaption>List of available assistant scripts.</figcaption>
<figcaption>Script catalog with search, sorting, and quick launch.</figcaption>
</figure>
<h2 id="solution">Solution</h2>
<p class="section__prose">
A local server and WebSocket connected Cursor to the plugin. Once a script was ready, I opened the plugin and clicked Run. The code was sent to Figma automatically.
</p>
<figure class="case-media case-media--real">
<img
src="data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7"
alt="AI assistant script editor"
alt="Script editor in the Figma plugin"
data-src="../../../assets/ai-assistant-figma/Script%20Edit.webp"
loading="lazy"
decoding="async"
data-image-viewer
/>
<figcaption>Script editor for running code in Figma.</figcaption>
<figcaption>Script screen before running it in Figma.</figcaption>
</figure>
<p class="section__prose">
Saved scripts could be launched from the catalog without Cursor. I ran existing scripts more often than I created new ones.
</p>
<figure class="case-media case-media--real">
<img
src="data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7"
alt="AI assistant script execution log"
data-src="../../../assets/ai-assistant-figma/Script%20Edit%20Log%20View.webp"
loading="lazy"
decoding="async"
data-image-viewer
/>
<figcaption>Script execution log view.</figcaption>
</figure>
<figure class="case-media case-media--real">
<img
src="data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7"
alt="AI assistant running indicator"
data-src="../../../assets/ai-assistant-figma/Script%20is%20Working.webp"
loading="lazy"
decoding="async"
data-image-viewer
/>
<figcaption>Active script execution indicator.</figcaption>
</figure>
<figure class="case-media case-media--real">
<img
src="data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7"
alt="AI assistant Live Mode"
data-src="../../../assets/ai-assistant-figma/Live%20Mode.webp"
loading="lazy"
decoding="async"
data-image-viewer
/>
<figcaption>Live Mode: interactive assistant mode.</figcaption>
</figure>
<figure class="case-media case-media--real">
<img
src="data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7"
alt="AI assistant More menu"
alt="Menu of additional script actions"
data-src="../../../assets/ai-assistant-figma/Menu%20More.webp"
loading="lazy"
decoding="async"
data-image-viewer
/>
<figcaption>More menu with extended actions.</figcaption>
<figcaption>Menu of additional actions for a script.</figcaption>
</figure>
<p class="section__prose">
To give the LLM better context, the plugin could copy information about a selected node or an entire page. I used that data in my conversation with the model.
</p>
<figure class="case-media case-media--real">
<img
src="data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7"
alt="Plugin toolbar with the Live toggle"
data-src="../../../assets/ai-assistant-figma/Live%20Mode.webp"
loading="lazy"
decoding="async"
data-image-viewer
/>
<figcaption>Script controls with the Live toggle.</figcaption>
</figure>
<p class="section__prose">
The LLM in Cursor could read the execution logs. If the issue was with the script's logic rather than a bug, I split it into small steps and ran them one by one. I tested each script in a separate Figma file first, then tried it in a working file when it behaved as expected.
</p>
<figure class="case-media case-media--real">
<img
src="data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7"
alt="Script editor with an execution log panel"
data-src="../../../assets/ai-assistant-figma/Script%20Edit%20Log%20View.webp"
loading="lazy"
decoding="async"
data-image-viewer
/>
<figcaption>Script editor and execution log panel.</figcaption>
</figure>
<figure class="case-media case-media--real">
@@ -514,9 +515,33 @@
Your browser does not support the video tag.
</video>
</div>
<figcaption>Demo of the AI assistant working in Figma.</figcaption>
<figcaption>Editing a script in Cursor and checking the result in Figma.</figcaption>
</figure>
<h2 id="result">Result</h2>
<aside class="case-callout" data-callout>
<span class="case-callout__emoji case-callout__emoji--pulse" aria-hidden="true">✅</span>
<div class="case-callout__content">
<p>I estimated that a task could take 1 to 30 minutes by hand. Launching its script then took one click.</p>
</div>
</aside>
<figure class="case-media case-media--real">
<img
src="data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7"
alt="Script execution indicator"
data-src="../../../assets/ai-assistant-figma/Script%20is%20Working.webp"
loading="lazy"
decoding="async"
data-image-viewer
/>
<figcaption>Indicator that a script is running.</figcaption>
</figure>
<p class="section__prose">
The time saved let me try more complex workflows. In working files, I often ran a script to flatten vector icons so they displayed correctly in production. Another turned a frame into a component, created an instance, and moved the master component to a designated place on the components page. Scripts also updated color tokens after manual changes and helped build a design-system file with many pages.
</p>
<p class="section__prose">
Other tasks included adding component variants, saving a set of tokens from JSON stored in a text layer, and building a prototype with keyboard-driven transitions. I also automated code syntax highlighting in a mockup to present an idea and tune the syntax colors. I would not have colored code by hand.
</p>
<figure class="case-media case-media--real">
<div class="case-video-shell">
<video controls preload="metadata" playsinline poster="../../../assets/ai-assistant-figma/video/20250913-0936-57.5977819.webp" data-case-video-player style="display: block; width: 100%; height: auto; margin: 0">
@@ -525,19 +550,8 @@
Your browser does not support the video tag.
</video>
</div>
<figcaption>Another example of the AI assistant working in Figma.</figcaption>
<figcaption>A script assembles a form from design-system components using a reference.</figcaption>
</figure>
<h2 id="result">Result</h2>
<p class="section__prose">
Depending on the script, a task that used to take 1 to 30 minutes now takes one click. This is my estimate, not a tracked measurement. The time saved let me try more complex workflows.
</p>
<p class="section__prose">
In working files, I often ran a script to flatten vector icons so they displayed correctly in production. Another turned a frame into a component, created an instance, and moved the master component to a designated place on the components page. Scripts also updated color tokens after manual changes and helped build a design-system file with many pages.
</p>
<p class="section__prose">
Other tasks included adding component variants, saving a set of tokens from JSON stored in a text layer, and building a prototype with keyboard-driven transitions. I also automated code syntax highlighting in a mockup to present an idea and tune the syntax colors. I would not have colored code by hand.
</p>
<p class="section__prose">
I learned more about the Figma Plugin API. Now I plan work with scriptable actions in mind, so I spend less time on repetitive steps.
</p>
+74 -60
View File
@@ -118,79 +118,80 @@
<p class="section__prose">
I wanted to remove the manual code handoff and run scripts directly in Figma. The plugin had to connect Cursor and Figma, let me reuse existing scripts, and make it easy to copy context about a selected node or an entire page for the LLM.
</p>
<h2 id="solution">Solution</h2>
<p class="section__prose">
A local server and WebSocket connected Cursor to the plugin. Once a script was ready, I opened the plugin and clicked Run. The code was sent to Figma automatically. The catalog saved scripts for reuse without Cursor. The plugin was not limited to one operation: I could add scripts for different tasks. Still, I ran them more often than I created new ones.
</p>
<p class="section__prose">
The plugin can copy details about a selected node or an entire page so the LLM can understand the design more accurately. The execution log was available to the LLM in Cursor. When a problem was about the script's logic, I broke it into small steps and ran them one by one. I tested scripts in a separate Figma file first, then tried them in a working file if everything behaved as expected.
</p>
<aside class="case-callout" data-callout>
<span class="case-callout__emoji case-callout__emoji--pulse" aria-hidden="true">💡</span>
<div class="case-callout__content">
<p>I could add scripts for different tasks to the catalog and run them directly in Figma.</p>
</div>
</aside>
<figure class="case-media case-media--real">
<img
src="data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7"
alt="AI assistant script list"
alt="Catalog of custom plugin scripts"
data-src="{{assetPrefix}}assets/ai-assistant-figma/Scripts%20List.webp"
loading="lazy"
decoding="async"
data-image-viewer
/>
<figcaption>List of available assistant scripts.</figcaption>
<figcaption>Script catalog with search, sorting, and quick launch.</figcaption>
</figure>
<h2 id="solution">Solution</h2>
<p class="section__prose">
A local server and WebSocket connected Cursor to the plugin. Once a script was ready, I opened the plugin and clicked Run. The code was sent to Figma automatically.
</p>
<figure class="case-media case-media--real">
<img
src="data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7"
alt="AI assistant script editor"
alt="Script editor in the Figma plugin"
data-src="{{assetPrefix}}assets/ai-assistant-figma/Script%20Edit.webp"
loading="lazy"
decoding="async"
data-image-viewer
/>
<figcaption>Script editor for running code in Figma.</figcaption>
<figcaption>Script screen before running it in Figma.</figcaption>
</figure>
<p class="section__prose">
Saved scripts could be launched from the catalog without Cursor. I ran existing scripts more often than I created new ones.
</p>
<figure class="case-media case-media--real">
<img
src="data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7"
alt="AI assistant script execution log"
data-src="{{assetPrefix}}assets/ai-assistant-figma/Script%20Edit%20Log%20View.webp"
loading="lazy"
decoding="async"
data-image-viewer
/>
<figcaption>Script execution log view.</figcaption>
</figure>
<figure class="case-media case-media--real">
<img
src="data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7"
alt="AI assistant running indicator"
data-src="{{assetPrefix}}assets/ai-assistant-figma/Script%20is%20Working.webp"
loading="lazy"
decoding="async"
data-image-viewer
/>
<figcaption>Active script execution indicator.</figcaption>
</figure>
<figure class="case-media case-media--real">
<img
src="data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7"
alt="AI assistant Live Mode"
data-src="{{assetPrefix}}assets/ai-assistant-figma/Live%20Mode.webp"
loading="lazy"
decoding="async"
data-image-viewer
/>
<figcaption>Live Mode: interactive assistant mode.</figcaption>
</figure>
<figure class="case-media case-media--real">
<img
src="data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7"
alt="AI assistant More menu"
alt="Menu of additional script actions"
data-src="{{assetPrefix}}assets/ai-assistant-figma/Menu%20More.webp"
loading="lazy"
decoding="async"
data-image-viewer
/>
<figcaption>More menu with extended actions.</figcaption>
<figcaption>Menu of additional actions for a script.</figcaption>
</figure>
<p class="section__prose">
To give the LLM better context, the plugin could copy information about a selected node or an entire page. I used that data in my conversation with the model.
</p>
<figure class="case-media case-media--real">
<img
src="data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7"
alt="Plugin toolbar with the Live toggle"
data-src="{{assetPrefix}}assets/ai-assistant-figma/Live%20Mode.webp"
loading="lazy"
decoding="async"
data-image-viewer
/>
<figcaption>Script controls with the Live toggle.</figcaption>
</figure>
<p class="section__prose">
The LLM in Cursor could read the execution logs. If the issue was with the script's logic rather than a bug, I split it into small steps and ran them one by one. I tested each script in a separate Figma file first, then tried it in a working file when it behaved as expected.
</p>
<figure class="case-media case-media--real">
<img
src="data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7"
alt="Script editor with an execution log panel"
data-src="{{assetPrefix}}assets/ai-assistant-figma/Script%20Edit%20Log%20View.webp"
loading="lazy"
decoding="async"
data-image-viewer
/>
<figcaption>Script editor and execution log panel.</figcaption>
</figure>
<figure class="case-media case-media--real">
@@ -201,9 +202,33 @@
Your browser does not support the video tag.
</video>
</div>
<figcaption>Demo of the AI assistant working in Figma.</figcaption>
<figcaption>Editing a script in Cursor and checking the result in Figma.</figcaption>
</figure>
<h2 id="result">Result</h2>
<aside class="case-callout" data-callout>
<span class="case-callout__emoji case-callout__emoji--pulse" aria-hidden="true">✅</span>
<div class="case-callout__content">
<p>I estimated that a task could take 1 to 30 minutes by hand. Launching its script then took one click.</p>
</div>
</aside>
<figure class="case-media case-media--real">
<img
src="data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7"
alt="Script execution indicator"
data-src="{{assetPrefix}}assets/ai-assistant-figma/Script%20is%20Working.webp"
loading="lazy"
decoding="async"
data-image-viewer
/>
<figcaption>Indicator that a script is running.</figcaption>
</figure>
<p class="section__prose">
The time saved let me try more complex workflows. In working files, I often ran a script to flatten vector icons so they displayed correctly in production. Another turned a frame into a component, created an instance, and moved the master component to a designated place on the components page. Scripts also updated color tokens after manual changes and helped build a design-system file with many pages.
</p>
<p class="section__prose">
Other tasks included adding component variants, saving a set of tokens from JSON stored in a text layer, and building a prototype with keyboard-driven transitions. I also automated code syntax highlighting in a mockup to present an idea and tune the syntax colors. I would not have colored code by hand.
</p>
<figure class="case-media case-media--real">
<div class="case-video-shell">
<video controls preload="metadata" playsinline poster="{{assetPrefix}}assets/ai-assistant-figma/video/20250913-0936-57.5977819.webp" data-case-video-player style="display: block; width: 100%; height: auto; margin: 0">
@@ -212,19 +237,8 @@
Your browser does not support the video tag.
</video>
</div>
<figcaption>Another example of the AI assistant working in Figma.</figcaption>
<figcaption>A script assembles a form from design-system components using a reference.</figcaption>
</figure>
<h2 id="result">Result</h2>
<p class="section__prose">
Depending on the script, a task that used to take 1 to 30 minutes now takes one click. This is my estimate, not a tracked measurement. The time saved let me try more complex workflows.
</p>
<p class="section__prose">
In working files, I often ran a script to flatten vector icons so they displayed correctly in production. Another turned a frame into a component, created an instance, and moved the master component to a designated place on the components page. Scripts also updated color tokens after manual changes and helped build a design-system file with many pages.
</p>
<p class="section__prose">
Other tasks included adding component variants, saving a set of tokens from JSON stored in a text layer, and building a prototype with keyboard-driven transitions. I also automated code syntax highlighting in a mockup to present an idea and tune the syntax colors. I would not have colored code by hand.
</p>
<p class="section__prose">
I learned more about the Figma Plugin API. Now I plan work with scriptable actions in mind, so I spend less time on repetitive steps.
</p>
+74 -61
View File
@@ -118,81 +118,81 @@
<p class="section__prose">
Я хотел убрать ручной перенос кода и запускать скрипты прямо из Figma. Плагин должен был связать Cursor с Figma, дать возможность повторно запускать уже созданные сценарии и быстро копировать для LLM контекст выбранного объекта или страницы.
</p>
<h2 id="solution">Решение</h2>
<p class="section__prose">
Локальный сервер и WebSocket связали Cursor с плагином. Когда скрипт готов, я открываю плагин и нажимаю «Выполнить». Код автоматически передаётся в Figma. Каталог сохраняет сценарии для повторного запуска без Cursor. Плагин не ограничен одной операцией: я могу добавлять скрипты под разные задачи. И всё же запускал их чаще, чем создавал новые.
</p>
<p class="section__prose">
Чтобы LLM точнее понимала макет, плагин умеет копировать информацию о выбранной ноде или целой странице. Логи выполнения мог читать LLM-бот в Cursor. Если проблема была в логике, я разбивал скрипт на небольшие шаги и проверял их по очереди. Сначала тестировал скрипт на отдельном файле. Когда всё работало, пробовал его в рабочем макете.
</p>
<aside class="case-callout" data-callout>
<span class="case-callout__emoji case-callout__emoji--pulse" aria-hidden="true">💡</span>
<div class="case-callout__content">
<p>Я мог добавлять в каталог скрипты под разные задачи и запускать их прямо в Figma.</p>
</div>
</aside>
<figure class="case-media case-media--real">
<img
src="data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7"
alt="Список скриптов AI-ассистента"
alt="Каталог пользовательских скриптов плагина"
data-src="{{assetPrefix}}assets/ai-assistant-figma/Scripts%20List.webp"
loading="lazy"
decoding="async"
data-image-viewer
/>
<figcaption>Список доступных скриптов ассистента.</figcaption>
<figcaption>Каталог сценариев с поиском, сортировкой и быстрым запуском.</figcaption>
</figure>
<h2 id="solution">Решение</h2>
<p class="section__prose">
Локальный сервер и WebSocket связали Cursor с плагином. Когда скрипт готов, я открываю плагин и нажимаю «Выполнить». Код автоматически передаётся в Figma.
</p>
<figure class="case-media case-media--real">
<img
src="data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7"
alt="Редактор скриптов AI-ассистента"
alt="Редактор скрипта в плагине Figma"
data-src="{{assetPrefix}}assets/ai-assistant-figma/Script%20Edit.webp"
loading="lazy"
decoding="async"
data-image-viewer
/>
<figcaption>Редактор скрипта для запуска в Figma.</figcaption>
<figcaption>Экран скрипта перед запуском в Figma.</figcaption>
</figure>
<p class="section__prose">
Сохранённые сценарии можно запускать из каталога и без Cursor. Я использовал готовые скрипты чаще, чем создавал новые.
</p>
<figure class="case-media case-media--real">
<img
src="data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7"
alt="Лог выполнения скрипта AI-ассистента"
data-src="{{assetPrefix}}assets/ai-assistant-figma/Script%20Edit%20Log%20View.webp"
loading="lazy"
decoding="async"
data-image-viewer
/>
<figcaption>Представление лога выполнения скрипта.</figcaption>
</figure>
<figure class="case-media case-media--real">
<img
src="data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7"
alt="Индикатор работы скрипта AI-ассистента"
data-src="{{assetPrefix}}assets/ai-assistant-figma/Script%20is%20Working.webp"
loading="lazy"
decoding="async"
data-image-viewer
/>
<figcaption>Индикатор активного выполнения скрипта.</figcaption>
</figure>
<figure class="case-media case-media--real">
<img
src="data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7"
alt="Live Mode AI-ассистента"
data-src="{{assetPrefix}}assets/ai-assistant-figma/Live%20Mode.webp"
loading="lazy"
decoding="async"
data-image-viewer
/>
<figcaption>Live Mode: интерактивный режим ассистента.</figcaption>
</figure>
<figure class="case-media case-media--real">
<img
src="data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7"
alt="Меню More AI-ассистента"
alt="Меню дополнительных действий со скриптом"
data-src="{{assetPrefix}}assets/ai-assistant-figma/Menu%20More.webp"
loading="lazy"
decoding="async"
data-image-viewer
/>
<figcaption>Дополнительное меню (More) с расширенными действиями.</figcaption>
<figcaption>Меню дополнительных действий со скриптом.</figcaption>
</figure>
<p class="section__prose">
Чтобы LLM точнее понимала макет, плагин копирует информацию о выбранной ноде или целой странице. Эти данные я использовал в диалоге с моделью.
</p>
<figure class="case-media case-media--real">
<img
src="data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7"
alt="Панель плагина с переключателем Live"
data-src="{{assetPrefix}}assets/ai-assistant-figma/Live%20Mode.webp"
loading="lazy"
decoding="async"
data-image-viewer
/>
<figcaption>Панель управления скриптом с переключателем Live.</figcaption>
</figure>
<p class="section__prose">
Логи выполнения мог читать LLM-бот в Cursor. Если дело было не в ошибке, а в логике скрипта, я разбивал его на небольшие шаги и запускал их по очереди. Сначала проверял сценарий на отдельном файле, а если всё работало, пробовал в рабочем макете.
</p>
<figure class="case-media case-media--real">
<img
src="data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7"
alt="Редактор скрипта с панелью логов"
data-src="{{assetPrefix}}assets/ai-assistant-figma/Script%20Edit%20Log%20View.webp"
loading="lazy"
decoding="async"
data-image-viewer
/>
<figcaption>Редактор и панель логов выполнения.</figcaption>
</figure>
<figure class="case-media case-media--real">
<div class="case-video-shell">
<video controls preload="metadata" playsinline poster="{{assetPrefix}}assets/ai-assistant-figma/video/20250904-1414-49.4157894.webp" data-case-video-player style="display: block; width: 100%; height: auto; margin: 0">
@@ -201,9 +201,33 @@
Ваш браузер не поддерживает видео.
</video>
</div>
<figcaption>Демонстрация работы AI-ассистента в Figma.</figcaption>
<figcaption>Доработка скрипта в Cursor и проверка результата в Figma.</figcaption>
</figure>
<h2 id="result">Результат</h2>
<aside class="case-callout" data-callout>
<span class="case-callout__emoji case-callout__emoji--pulse" aria-hidden="true">✅</span>
<div class="case-callout__content">
<p>По моей оценке, на задачу вручную уходило от 1 до 30 минут. Запустить сценарий теперь можно было одним нажатием.</p>
</div>
</aside>
<figure class="case-media case-media--real">
<img
src="data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7"
alt="Индикатор выполнения скрипта"
data-src="{{assetPrefix}}assets/ai-assistant-figma/Script%20is%20Working.webp"
loading="lazy"
decoding="async"
data-image-viewer
/>
<figcaption>Индикатор активного выполнения скрипта.</figcaption>
</figure>
<p class="section__prose">
Высвободившееся время позволяло браться за более сложные рабочие сценарии. В рабочих файлах я часто запускал скрипт, который сводил векторные иконки через flatten для корректного отображения в продакшене. Другой превращал фрейм в компонент, создавал его инстанс и переносил мастер-компонент в заданное место на странице компонентов. Скрипты также обновляли цветовые токены после ручных изменений и помогали собрать файл дизайн-системы с множеством страниц.
</p>
<p class="section__prose">
Были и другие задачи: добавить варианты компонентов, сохранить набор токенов из JSON в текстовом слое или собрать прототип с переходами по клавиатуре. Я автоматизировал и подсветку кода в макете, чтобы показать идею и подобрать цвета синтаксиса. Вручную я бы за это не взялся.
</p>
<figure class="case-media case-media--real">
<div class="case-video-shell">
<video controls preload="metadata" playsinline poster="{{assetPrefix}}assets/ai-assistant-figma/video/20250913-0936-57.5977819.webp" data-case-video-player style="display: block; width: 100%; height: auto; margin: 0">
@@ -212,19 +236,8 @@
Ваш браузер не поддерживает видео.
</video>
</div>
<figcaption>Ещё один пример работы AI-ассистента в Figma.</figcaption>
<figcaption>Сборка формы из компонентов дизайн-системы по референсу с помощью скрипта.</figcaption>
</figure>
<h2 id="result">Результат</h2>
<p class="section__prose">
В зависимости от скрипта задача, которая раньше занимала от 1 до 30 минут, теперь выполнялась одним нажатием. Это моя оценка, отдельную статистику я не собирал. Высвободившееся время позволяло браться за более сложные рабочие сценарии.
</p>
<p class="section__prose">
В рабочих файлах я часто запускал скрипт, который сводил векторные иконки через flatten для корректного отображения в продакшене. Другой превращал фрейм в компонент, создавал его инстанс и переносил мастер-компонент в заданное место на странице компонентов. Скрипты также обновляли цветовые токены после ручных изменений и помогали собрать файл дизайн-системы с множеством страниц.
</p>
<p class="section__prose">
Были и другие задачи: добавить варианты компонентов, сохранить набор токенов из JSON в текстовом слое или собрать прототип с переходами по клавиатуре. Я автоматизировал и подсветку кода в макете, чтобы показать идею и подобрать цвета синтаксиса. Вручную я бы за это не взялся.
</p>
<p class="section__prose">
За время работы я лучше разобрался в Figma Plugin API. Теперь при планировании заранее замечаю, какие действия можно скриптовать, чтобы не тратить время на повторяющиеся операции.
</p>