Files
figma-ai-plugin/KNOWLEDGE.md
T

114 lines
12 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# Knowledge — Figma AI Plugin
> Копилка находок и решений по проекту. Не наступай на грабли дважды.
> Пополняется по ходу разработки. Формат: проблема → решение (+ контекст/ссылка).
> Hermes имеет право править и дополнять этот файл самостоятельно (см. IDEA.md).
## Сборка / окружение
### Синхронизация билда на Matebook: архив должен сохранять `build/`
- **Симптом:** архив на Matebook есть, но Figma продолжает показывать старую версию.
- **Причина:** flat-архив, созданный через `zip -j`, складывает `main.js` и `ui.js` в корень. Распаковка обновляет `manifest.json`, но не заменяет `D:\Figma Plugins\figma-ai-plugin\build\main.js` и `build\ui.js`, на которые ссылается манифест.
- **Решение:** архивировать из корня проекта с путями (`tar czf /tmp/figma-ai-plugin.tar.gz --exclude=node_modules --exclude=.git .`), проверить список файлов, затем распаковать в целевую папку. Для zip использовать `zip -r`, не `zip -j`. После распаковки сверить SHA-256 локальных и удалённых `build/main.js`, `build/ui.js`, `manifest.json`; дополнительно проверить маркер `0.1.N` в удалённом `build/ui.js`.
- **Проверка цели:** наличие архива в `C:\Users\risow\Downloads` не является успешным деплоем. Успешный deploy подтверждается только файлами в `D:\Figma Plugins\figma-ai-plugin\build\`.
- **Ссылка:** IDEA.md, раздел «Рабочий флоу».
### TypeScript 7.x ломает `@create-figma-plugin/build`
- **Симптом:** `TypeError: Cannot read properties of undefined (reading 'getCurrentDirectory')` при `build-figma-plugin`.
- **Причина:** `build-figma-plugin` ожидает `ts.sys`, которого нет в TS 7.
- **Решение:** зафиксировать `typescript` на `~5.6.3` в `package.json` devDependencies.
- **Ссылка:** package.json
### tsconfig: не оверрайдить `jsx` на `react-jsx`
- **Симптом:** `error TS5089: Option 'jsxFactory' cannot be specified when option 'jsx' is 'react-jsx'`.
- **Причина:** базовый `@create-figma-plugin/tsconfig` уже задаёт `jsx: react` + `jsxFactory: h`.
- **Решение:** в проектном tsconfig только `extends` + добавляем `lib`/`types`. Не трогать `jsx`/`jsxFactory`. Preact `h` уже импортируется в `ui.tsx`.
- **Ссылка:** tsconfig.json
### `Text muted` не существует — используй `Muted`
- **Симптом:** `Property 'muted' does not exist on type ... Text`.
- **Решение:** для приглушённого текста брать компонент `<Muted>` из `@create-figma-plugin/ui`, а не проп `muted` у `<Text>`.
- **Ссылка:** src/ui.tsx
### Кнопка-иконка рядом с другими IconButton — бери РОДНУЮ иконку, не инлайн-SVG
- **Симптом:** иконка копирования рядом с кнопкой развернуть выглядит «другого размера»/тоньше, хотя `viewBox` один (`24×24`).
- **Причина:** `IconButton` из `@create-figma-plugin/ui` оборачивает иконку в `<div class="icon">` (`position:absolute`, БЕЗ задания размера) — размер берётся целиком из самой SVG. Родные иконки сета (`IconExpand24`, `IconCheck24`, `IconCopySmall24` и т.п.) — **залитые** (`fill="currentColor"`). Моя инлайн-SVG была **контурной** (`stroke`, `fill="none"`, `stroke-width=2`) — на том же `24×24` viewBox контурные lucide-иконки визуально кажутся меньше и легче, чем залитые соседки. Отсюда ощущение «разные размеры».
- **Правило (как делать правильно):**
1. Рядом с `IconButton` НИКОГДА не ставить текстовую `<Button>` с лейблом — только `IconButton` (пользователь прямо сказал: *"Очевидно же, что там достаточно кнопки иконки"*).
2. Брать иконку из родного сета `@create-figma-plugin/ui` (он же — адаптация lucide, залитые 24px): `IconCopySmall24`, `IconDuplicateSmall24`, `IconClipboardSmall24`, `IconCheck24`, `IconExpand24` и т.д. — гарантированно совпадёт по габариту и весу с соседями.
3. Если нужной иконки в сете нет (напр. copy/clipboard там только 16px `-small`), и ты делаешь инлайн-SVG — делай её **залитой** (`fill="currentColor"`, без `stroke`), `width/height=24`, `viewBox="0 0 24 24`, чтобы вес совпал с родными. Контурные (`stroke`) иконки lucide рядом с залитыми соседями НЕ класть.
4. Подтверждение действия (копирование) — переключать иконку на `IconCheck24` на ~1.2 с, без текстовой подписи.
- **Ссылка:** node_modules/@create-figma-plugin/ui/lib/components/icon-button/icon-button.module.css (`.icon` без размера), icon-24/icon-*-24.js (залитые SVG), src/ui.tsx (кнопки в тулбаре).
### Плагин не запускается в Figma — нет папки `build/` на Matebook
- **Симптом:** плагин не открывается / Figma молча ничего не делает при Run (ошибка не всегда видна).
- **Причина:** `manifest.json` указывает `main: build/main.js` и `ui: build/ui.js`, но в скопированной на Matebook папке папки `build/` нет (старая команда синхронизации исключала её через `--exclude build`).
- **Решение:** пересобрать на VPS (`npm run build`) и залить на Matebook ВЕСЬ проект вместе с `build/` — исключать только `node_modules` и `.git` (они для запуска в Figma не нужны, Figma исполняет собранные `build/*.js`). После распаковки проверить наличие `build/main.js` и `build/ui.js`.
- **Ссылка:** IDEA.md (раздел «Рабочий флоу», шаг 4), этот файл (раздел синхронизации через tar).
## Рабочий флоу (VPS → Matebook → Figma)
### Копия на Matebook через tar (rsync/scp с пробелами в пути падают)
- **Симптом:** `rsync: command not found` (на Windows), `scp: ambiguous target` (пробел в пути).
- **Решение:**
1. На VPS: `npm run build` (обязательно — иначе нет папки `build/`)
2. На VPS: `tar czf /tmp/x.tar.gz --exclude node_modules --exclude .git .` ← `build/` НЕ исключать!
3. `scp /tmp/x.tar.gz risow@10.200.201.5:D:/x.tar.gz`
4. На Matebook (PowerShell): `Set-Location 'D:/Figma Plugins/figma-ai-plugin'; tar xzf 'D:/x.tar.gz'`
- **Ловушка:** старая команда исключала `--exclude build` → в папке плагина на Matebook не было `build/`, и Figma не находила `build/main.js`/`build/ui.js` → плагин не запускался. См. gotcha «Плагин не запускается — нет `build/`».
- **Ссылка:** IDEA.md (раздел «Рабочий флоу»)
### Gitea push через токен в URL
- **Симптом:** `could not read Username` при `git push` (нет credential helper).
- **Решение:** remote как `http://<TOKEN>:@<host>/admin/figma-ai-plugin.git`. Токен должен иметь scope `write:repository` (без `write:user` создать репо нельзя — создавать через basic auth admin-ом).
- **Ссылка:** IDEA.md, Gitea http://x1qnvk08zec2u5cx6yh5iexh.155.212.186.39.sslip.io/admin/figma-ai-plugin
## ЭТАЛОН — ресайз и позиционирование (подтверждено пользователем)
> Зафиксировано после коммита `47cad79`. Любые правки в `ui.tsx`/`main.ts` сверять с этим.
> Среда замера: zoom=1, Figma UI виден (лимит окна ≈ 454×783 при full HD viewport).
### Модель координат
- `reposition(x,y)` / `getPosition().canvasSpace` — В canvas-space, отсчёт от **верха шапки** окна плагина (38px).
- `resize(w,h)` — в ЭКРАННЫХ px. Figma КЛАМПИТ до своего лимита при видимом UI (≈454×783), при спрятанном UI (Ctrl+\) — до всего viewport.
- Перевод: `wCanvas = w/zoom`, `hCanvasFull = (38+h)/zoom`.
### Периметральные ручки (8 фиолетовых div)
- **Drag** (>4px) = ресайз (single-/dual-axis). Якорь фиксируется в `RESIZE_START`, размер считается от якоря.
- **Чистый клик** (без движения):
- Угол **не в доке** → телепорт в угол (`dockWindow`).
- Угол **в доке** (край) → свободная ось = 50% viewport (`DOCK_HALF`), прижим в угол, выход из дока.
- Край → телепорт в край (`dockWindow`).
- Центр — ТОЛЬКО кнопкой в шапке (в периметр не входит).
### Что есть «док»
- **Док = окно растянуто у КРАЯ** (одна ось = 320, другая = max viewport). Углы и центр доком НЕ считаются.
- Краевые кнопки (▬▭▏▕) пишут `dockedPosRef`; углы/центр — нет.
### Ожидаемые значения (zoom=1, bounds 3513,-1774 · 908×872, видимый UI)
Реальный лимит: maxW≈454, maxH≈783. Растяжение срабатывает ТОЛЬКО по «своей» оси (другая клампится):
| Кнопка | Реал. W×H | x | y | relX | relY |
|---|---|---|---|---|---|
| ◤ top-left | 454×417 | 3513 | -1774 | 0 | 0 |
| ▬ top-center | 454×320 | 3740 | -1774 | 227 | 0 |
| ◥ top-right | 454×417 | 3867 | -1774 | 354 | 0 |
| ▏ center-left | 320×783 | 3513 | -1748 | 0 | 26 |
| ⊕ center | 454×417 | 3740 | -1565 | 227 | 209 |
| ▕ center-right | 320×783 | 4101 | -1748 | 588 | 26 |
| ◣ bottom-left | 454×417 | 3513 | -1357 | 0 | 417 |
| ▭ bottom-center | 454×320 | 3740 | -1260 | 227 | 514 |
| ◢ bottom-right | 454×417 | 3867 | -1357 | 354 | 417 |
- `▬ top-center`: relX=227 (окно ПО ЦЕНТРУ по X), relY=0 (прижат к верху).
- `▏ center-left`: relY=26, gapT=gapB=25 (вертикально ОТЦЕНТРИРОВАНО).
- Баг детектора: если видишь relX=0 на `▬` — окно прижалось к левому краю вместо центра (позиция считается от канона, а не реального размера). Фикс: `DOCK_REFINE` считает от реального `window.innerWidth/Height`.
### Кнопки в шапке
`[размер] [copy] [центр=IconDockToSide24] [развернуть/свернуть]`. Сетка 3×3 из тела УДАЛЕНА.
## Ресурсы (не терять)
- UI Storybook: https://yuanqing.github.io/create-figma-plugin/ui/
- Figma Plugin API docs: https://www.figma.com/plugin-docs/
- Исходный плагин «AI assistant» (движок): `D:\YandexDisk\Figma Plugins DEVs\AI assistant` (Matebook)