Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
131 commits
Select commit Hold shift + click to select a range
6afc42a
feat: добавлен генератор дизайн-токенов
fabulous-unicorn Jul 30, 2026
4ba8ef8
ci: добавлены проверки дизайн-токенов
fabulous-unicorn Jul 30, 2026
a32318c
feat: добавлены и подключены дизайн-токены
fabulous-unicorn Jul 30, 2026
62503f8
fix: исправлена нормализация радиусов в токенах
fabulous-unicorn Jul 30, 2026
49298ad
fix: доработан генератор дизайн-токенов
fabulous-unicorn Jul 31, 2026
1a3b45e
chore: исправлены команды проверки дизайн-токенов
fabulous-unicorn Jul 31, 2026
13a885a
feat: добавлена поддержка focusRing-токенов
fabulous-unicorn Jul 31, 2026
1e50c64
feat: добавлена поддержка токенов анимации
fabulous-unicorn Jul 31, 2026
7be9f69
feat: добавлена генерация токенов шрифтов
fabulous-unicorn Aug 3, 2026
9087124
refactor(tokens): разделены semantic-токены
fabulous-unicorn Aug 4, 2026
95aedfe
refactor(tokens): component-токены скрыты из публичного API
fabulous-unicorn Aug 4, 2026
7fb6f02
docs: актуализирована документация тем и токенов
fabulous-unicorn Aug 4, 2026
9e004ca
refactor(tokens): объединены проверка и форматирование генерации
fabulous-unicorn Aug 4, 2026
a9965b4
feat(Theme): подключены сгенерированные токены
fabulous-unicorn Aug 4, 2026
8c3f763
feat(Accordion): подключены сгенерированные токены
fabulous-unicorn Aug 4, 2026
164cb7c
feat(Avatar): подключены сгенерированные токены
fabulous-unicorn Aug 4, 2026
7b8547a
feat(Badge): подключены сгенерированные токены
fabulous-unicorn Aug 4, 2026
369bfe4
feat(Button): подключены сгенерированные токены
fabulous-unicorn Aug 4, 2026
7ec92ba
feat(Checkbox): подключены сгенерированные токены
fabulous-unicorn Aug 4, 2026
0bd3a21
feat(Chip): подключены сгенерированные токены
fabulous-unicorn Aug 4, 2026
0a1b491
feat(Dialog): подключены сгенерированные токены
fabulous-unicorn Aug 4, 2026
2ed02ab
feat(Divider): подключены сгенерированные токены
fabulous-unicorn Aug 4, 2026
222234d
feat(InputSwitch): подключены сгенерированные токены
fabulous-unicorn Aug 4, 2026
3af0b0e
feat(Input): подключены сгенерированные токены
fabulous-unicorn Aug 4, 2026
61d78dd
feat(List): подключены сгенерированные токены
fabulous-unicorn Aug 4, 2026
618185e
feat(MenuItem): подключены сгенерированные токены
fabulous-unicorn Aug 4, 2026
af5f1ab
feat(Message): подключены сгенерированные токены
fabulous-unicorn Aug 4, 2026
2e007bb
feat(ProgressBar): подключены сгенерированные токены
fabulous-unicorn Aug 4, 2026
f76b9ba
feat(ProgressSpinner): подключены сгенерированные токены
fabulous-unicorn Aug 4, 2026
4494a87
feat(RadioButton): подключены сгенерированные токены
fabulous-unicorn Aug 4, 2026
9300663
feat(Rating): подключены сгенерированные токены
fabulous-unicorn Aug 4, 2026
e9ed0da
feat(SelectButton): подключены сгенерированные токены
fabulous-unicorn Aug 4, 2026
b694483
feat(Skeleton): подключены сгенерированные токены
fabulous-unicorn Aug 4, 2026
faf0d34
feat(Slider): подключены сгенерированные токены
fabulous-unicorn Aug 4, 2026
73fa787
feat(Tabs): подключены сгенерированные токены
fabulous-unicorn Aug 4, 2026
27dafce
feat(Tag): подключены сгенерированные токены
fabulous-unicorn Aug 4, 2026
0006c35
feat(Timer): подключены сгенерированные токены
fabulous-unicorn Aug 4, 2026
9beb3ac
feat(ToggleButton): подключены сгенерированные токены
fabulous-unicorn Aug 4, 2026
d58df8b
feat(Typography): подключены сгенерированные токены
fabulous-unicorn Aug 4, 2026
a621cd5
refactor(theme): добавлен слой legacy-совместимости
fabulous-unicorn Aug 4, 2026
7b3f545
chore: release v1.1.0-beta.0
fabulous-unicorn Aug 6, 2026
77d329e
fix(tokens): обводка Avatar переведена на inverse
Aug 12, 2026
89aceb8
fix(tokens): цвет контента Divider переведён на fg.muted
Aug 12, 2026
6d73a8e
fix(Slider): лейблы значений берут цвет из темы
Aug 12, 2026
3c79219
fix(tokens): иконка checked-состояния Checkbox переведена на inverse
Aug 12, 2026
9d62f9f
fix(tokens): скругление Dialog переведено с max на borderRadius.500
Aug 12, 2026
f1d4ace
fix(Tabs): активная линия выровнена с линией таб-листа
Aug 12, 2026
e4a3731
fix(tokens): фон трека InputSwitch в тёмной теме приведён к макету
Aug 12, 2026
34a9989
fix(tokens): фон ручки InputSwitch переведён на semantic-роли по макету
Aug 12, 2026
449c65d
fix(InputSwitch): ручка в disabled берёт цвет из токена
Aug 12, 2026
59e2e0b
docs: добавлен навык UI Kit Figma
fabulous-unicorn Aug 13, 2026
eaffb59
docs(skill): запрещено изменять файлы токенов
fabulous-unicorn Aug 14, 2026
83a971f
docs: закреплён русский язык сообщений коммитов
fabulous-unicorn Aug 13, 2026
e9656b8
chore(tokens): обновлены токены компонентов
fabulous-unicorn Aug 13, 2026
4041144
feat(badge): добавлены размеры Badge
fabulous-unicorn Aug 13, 2026
628bf8f
fix(button): исправлено центрирование и отображение вариантов
fabulous-unicorn Aug 13, 2026
266d7e2
fix(list): исправлено отображение базовой стори
fabulous-unicorn Aug 13, 2026
4283c3f
docs: обновлены ссылки компонентов на Figma
fabulous-unicorn Aug 14, 2026
c18da67
refactor(stories): изменённые стори переведены на JSX
fabulous-unicorn Aug 14, 2026
22d55d2
fix(styles): заменён устаревший absoluteFillObject
fabulous-unicorn Aug 14, 2026
c38b6dd
feat(input-otp): скорректировано поведение компонента
fabulous-unicorn Aug 25, 2026
9c79891
fix(input-otp): исправлен повторный ввод после ошибки
fabulous-unicorn Aug 26, 2026
1d4aff6
fix(input-otp): исправлены каретка и сценарий ошибки
fabulous-unicorn Sep 2, 2026
9695b5b
fix(input-otp): синхронизированы стили с макетом
fabulous-unicorn Sep 2, 2026
1b79ff0
fix(tokens): поддержаны неполные цветовые схемы компонентов
fabulous-unicorn Sep 2, 2026
38c7638
chore(tokens): обновлены дизайн-токены
fabulous-unicorn Sep 2, 2026
bf0c2a0
fix(input-otp): синхронизированы состояния ошибки
fabulous-unicorn Sep 2, 2026
83e6de2
fix(input-otp): синхронизированы токены с макетом
fabulous-unicorn Sep 8, 2026
b17aafa
fix(input-otp): исправлено масштабирование и центрирование текста
fabulous-unicorn Sep 11, 2026
eeab5cf
feat(button): обновлён API и поведение кнопок
fabulous-unicorn Oct 2, 2026
f682cd5
refactor(button): разделены оформление и общая логика кнопок
fabulous-unicorn Oct 5, 2026
f997c15
fix(button): синхронизированы размеры и поддержан рост текста
fabulous-unicorn Oct 5, 2026
97bd926
fix(button): сохранена геометрия link при увеличении текста
fabulous-unicorn Oct 6, 2026
4e188c6
fix(button): синхронизированы токены и привязки с Figma
fabulous-unicorn Oct 7, 2026
e5bd53f
feat(badge): добавлены primary, доступность и масштабирование текста
fabulous-unicorn Oct 6, 2026
a1b6168
fix(tokens): обновлён радиус Badge и перегенерированы темы
fabulous-unicorn Oct 6, 2026
6604a10
refactor(badge): стили вынесены в отдельный файл
fabulous-unicorn Oct 6, 2026
7000144
fix(badge): упрощено измерение и исправлено центрирование текста
fabulous-unicorn Oct 6, 2026
2b45c42
fix(tokens): уменьшен радиус Badge до 100
fabulous-unicorn Oct 8, 2026
095f7d7
test: актуализировать снапшоты компонентов для текущих токенов
fabulous-unicorn Oct 13, 2026
4394a17
fix(skeleton): обновлены API, доступность и токены
fabulous-unicorn Oct 19, 2026
586c940
docs(skeleton): добавлена документация компонента
fabulous-unicorn Oct 20, 2026
869e037
fix(storybook): уменьшен шрифт названий пропов
fabulous-unicorn Oct 23, 2026
3325a0c
fix(tokens): синхронизированы токены полей ввода с Figma
fabulous-unicorn Oct 13, 2026
6ff223e
refactor(input-switch): компонент перенесён в отдельную папку
fabulous-unicorn Oct 8, 2026
ccaf8ce
refactor(input-otp): компонент перенесён в отдельную папку
fabulous-unicorn Oct 8, 2026
03e3a59
chore(storybook): упорядочены истории и настройка форматирования
fabulous-unicorn Oct 8, 2026
12fe4b8
refactor(input): вынесены legacy-компоненты и сохранены старые экспорты
fabulous-unicorn Oct 8, 2026
85a5f9d
feat(input): добавлен InputCaption
fabulous-unicorn Oct 12, 2026
4b251df
feat(input): добавлен InputGroupAddon
fabulous-unicorn Oct 12, 2026
fb76513
feat(input): добавлен InputText с новым API
fabulous-unicorn Oct 12, 2026
fb24fef
feat(input): добавлен InputGroup с базовой доступностью
fabulous-unicorn Oct 12, 2026
a449b59
feat(input): добавлен Password с базовой доступностью
fabulous-unicorn Oct 12, 2026
f289d67
fix(input): улучшена доступность полей и подписей
fabulous-unicorn Oct 12, 2026
a305084
fix(input): упрощено озвучивание полей и подписей
fabulous-unicorn Oct 12, 2026
c2f0640
docs(input): добавлена документация компонентов ввода
fabulous-unicorn Oct 13, 2026
645ac2e
fix(input): стабилизированы высота и масштабирование подписей
fabulous-unicorn Oct 19, 2026
dc1f6ad
docs(input): уточнена и упрощена документация полей ввода
fabulous-unicorn Oct 20, 2026
24f1930
fix(input): исправлено отображение плавающего лейбла и привязки токенов
fabulous-unicorn Oct 23, 2026
bb822c4
refactor(input): разделены раскладка поля и оформление кнопок
fabulous-unicorn Oct 23, 2026
a8837e2
feat(tag): обновлены API, иконки и доступность
fabulous-unicorn Oct 19, 2026
6bccbf1
fix(tag): исправлено отображение при изменении масштаба шрифта
fabulous-unicorn Oct 20, 2026
e5eb793
docs(tag): добавлена документация компонента
fabulous-unicorn Oct 20, 2026
a8330b4
fix(tag): исправлен цвет текста в тёмной теме
fabulous-unicorn Oct 20, 2026
9eda205
fix(fonts): подключены недостающие начертания
fabulous-unicorn Oct 20, 2026
c08b6df
feat(button): добавить поддержку badge
fabulous-unicorn Oct 23, 2026
0921154
test(button): удалить старые тесты ButtonSeverity
fabulous-unicorn Oct 23, 2026
6620129
fix(button): исправить позицию точки и controls бейджа
fabulous-unicorn Oct 23, 2026
ceb2540
fix(storybook): добавлены префиксы параметров бейджа
fabulous-unicorn Oct 23, 2026
789cdbe
fix(tokens): обновлены токены
fabulous-unicorn Oct 26, 2026
abe84ee
feat(toggle-switch): добавлен ToggleSwitch
fabulous-unicorn Oct 26, 2026
5a9b16b
docs(toggle-switch): добавлены документация и стори
fabulous-unicorn Oct 26, 2026
8f69dfe
docs(input): восстановлены стори группы Input
fabulous-unicorn Oct 27, 2026
1f58423
docs(input-switch): восстановлена стори InputSwitch
fabulous-unicorn Oct 27, 2026
5e17ab3
docs(typography): добавлена стори Overview для типографии
fabulous-unicorn Oct 27, 2026
127a068
feat(storybook): добавлены метки состояния компонентов
fabulous-unicorn Oct 27, 2026
c67eda3
chore(storybook): настроен порядок разделов и сторис
fabulous-unicorn Oct 27, 2026
33d65c6
docs(storybook): объединены сторис компонентов форм
fabulous-unicorn Oct 27, 2026
e092f05
docs(storybook): сгруппированы меню и вкладки
fabulous-unicorn Oct 27, 2026
da94cb3
docs(dialog): объединены варианты диалога в одной стори
fabulous-unicorn Oct 27, 2026
8fb2a1e
docs(accordion): упрощена интерактивная стори аккордеона
fabulous-unicorn Oct 27, 2026
9b47838
docs(storybook): переименованы группы полей ввода и рейтинга
fabulous-unicorn Oct 27, 2026
78e518f
docs(storybook): перенесены стори устаревших компонентов в общие группы
fabulous-unicorn Oct 27, 2026
9dc8d6d
fix(storybook): исправлен регистр метки design pending
fabulous-unicorn Oct 27, 2026
40fda37
fix(storybook): исправлена очистка поля LegacyInputMask
fabulous-unicorn Oct 27, 2026
d07ddf1
feat(storybook): добавлена метка исключения из версии 2.0
fabulous-unicorn Oct 27, 2026
2e624b0
docs(storybook): отмечены устаревшие компоненты меню
fabulous-unicorn Oct 27, 2026
8caae4d
docs(storybook): отмечены компоненты для проверки дизайна
fabulous-unicorn Oct 27, 2026
69ab370
refactor(storybook): упрощён экспорт стори Dialog
fabulous-unicorn Oct 28, 2026
475ecba
chore(skills): обновлены проектные навыки и проверки
fabulous-unicorn Oct 28, 2026
2103b4a
chore(skills): расширены навыки API, Figma и Storybook
fabulous-unicorn Oct 28, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
The table of contents is too big for display.
Diff view
Diff view
  •  
  •  
  •  
159 changes: 159 additions & 0 deletions .agents/scripts/check-skills.mjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,159 @@
import assert from 'node:assert/strict'
import { existsSync, readFileSync, readdirSync } from 'node:fs'
import { dirname, join, relative, resolve, sep } from 'node:path'
import process from 'node:process'
import { pathToFileURL } from 'node:url'

import { parse } from 'yaml'

const read = (file) => readFileSync(file, 'utf8')

const readMapping = (text) => {
const value = parse(text)
assert(
value && typeof value === 'object' && !Array.isArray(value),
'expected YAML mapping'
)

return value
}

const checkFrontmatter = (file, name) => {
const match = read(file).match(
/^---\r?\n(?<metadata>[\s\S]*?)\r?\n---(?:\r?\n|$)/u
)
assert(match, 'missing YAML frontmatter')
const metadata = readMapping(match.groups.metadata)
assert(
/^[a-z0-9]+(?:-[a-z0-9]+)*$/u.test(name) && name.length <= 64,
'invalid skill name'
)
assert.equal(metadata.name, name, 'name must match the skill directory')
assert(
typeof metadata.description === 'string' && metadata.description.trim(),
'missing description'
)
}

const checkManifest = (file, name) => {
const metadata = readMapping(read(file))

if (metadata.interface === undefined) return

const ui = metadata.interface
assert(
ui && typeof ui === 'object' && !Array.isArray(ui),
'invalid interface mapping'
)

for (const [key, value] of Object.entries(ui)) {
assert(
typeof value === 'string' && value.trim(),
`invalid interface.${key}`
)
}

if (ui.short_description !== undefined) {
assert(
ui.short_description.length >= 25 && ui.short_description.length <= 64,
'short_description must be 25–64 characters'
)
}

if (ui.default_prompt !== undefined) {
assert(
ui.default_prompt.includes(`$${name}`),
'default_prompt must mention its skill'
)
}
}

const checkLinks = (file, skillRoot) => {
const text = read(file).replace(
/^(?<fence>`{3,}|~{3,})[^\n]*\n[\s\S]*?^\k<fence>[ \t]*$/gmu,
''
)

for (const {
groups: { target },
} of text.matchAll(/\[[^\]]*\]\((?<target>[^)]+)\)/gu)) {
const path = target.trim().replace(/^<|>$/gu, '')

if (!/^[a-z][a-z0-9+.-]*:/iu.test(path) && !path.startsWith('#')) {
assert(
existsSync(
resolve(dirname(file), decodeURIComponent(path.split('#')[0]))
),
`missing link target: ${target}`
)
}
}

for (const {
groups: { target },
} of text.matchAll(/`(?<target>(?:references|scripts|assets)\/[^`\s]+)`/gu)) {
assert(existsSync(join(skillRoot, target)), `missing resource: ${target}`)
}
}

export const checkSkills = (repoRoot) => {
const errors = []
const check = (file, action) => {
try {
action()
} catch (error) {
errors.push(`${relative(repoRoot, file)}: ${error.message}`)
}
}
const skillsRoot = join(repoRoot, '.agents/skills')
const names = readdirSync(skillsRoot, { withFileTypes: true })
.filter((entry) => entry.isDirectory() && !entry.name.startsWith('.'))
.map((entry) => entry.name)

for (const name of names) {
const root = join(skillsRoot, name)
const entry = join(root, 'SKILL.md')
check(entry, () => checkFrontmatter(entry, name))
const manifest = join(root, 'agents/openai.yaml')

if (existsSync(manifest))
check(manifest, () => checkManifest(manifest, name))

const references = join(root, 'references')
const documents = existsSync(references)
? readdirSync(references, { recursive: true })
.filter(
(path) =>
path.endsWith('.md') && !path.split(sep).includes('vendor')
)
.map((path) => join(references, path))
: []

for (const file of [entry, ...documents])
check(file, () => checkLinks(file, root))
}

const agents = join(repoRoot, 'AGENTS.md')
check(agents, () => {
for (const {
groups: { name },
} of read(agents).matchAll(/\$(?<name>[a-z][a-z0-9-]*)/gu)) {
assert(names.includes(name), `unknown project skill: ${name}`)
}
})

return errors
}

if (import.meta.url === pathToFileURL(resolve(process.argv[1])).href) {
const errors = checkSkills(resolve(import.meta.dirname, '../..'))

if (errors.length) {
console.error(errors.join('\n'))
process.exitCode = 1
} else {
console.log(
'Project skill metadata, links, and AGENTS.md routing are valid.'
)
}
}
88 changes: 88 additions & 0 deletions .agents/scripts/test-check-skills.mjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
import assert from 'node:assert/strict'
import { mkdirSync, mkdtempSync, rmSync, writeFileSync } from 'node:fs'
import { tmpdir } from 'node:os'
import { dirname, join } from 'node:path'
import { test } from 'node:test'

import { checkSkills } from './check-skills.mjs'

const fixture = (context) => {
const root = mkdtempSync(join(tmpdir(), 'ui-kit-skills-'))
context.after(() => rmSync(root, { recursive: true, force: true }))
const write = (path, text) => {
const file = join(root, path)
mkdirSync(dirname(file), { recursive: true })
writeFileSync(file, text)
}
write('AGENTS.md', 'Use $sample.\n')
write(
'.agents/skills/sample/SKILL.md',
'---\nname: sample\ndescription: Example skill\n---\n[Guide](references/guide.md)\n'
)
write('.agents/skills/sample/references/guide.md', '# Guide\n')
write(
'.agents/skills/sample/agents/openai.yaml',
'interface:\n short_description: "Describe a valid example skill"\n default_prompt: "Use $sample for this task."\n'
)

return { root, write }
}

test('accepts valid metadata, linked references, and project routing', (context) => {
const { root, write } = fixture(context)
write('.agents/skills/sample/vendor/copied/SKILL.md', 'not active metadata')
assert.deepEqual(checkSkills(root), [])
})

test('reports malformed YAML in entrypoints and manifests', (context) => {
const { root, write } = fixture(context)
write(
'.agents/skills/sample/SKILL.md',
'---\nname: sample\nname: duplicate\n---\n'
)
write('.agents/skills/sample/agents/openai.yaml', 'interface: [\n')
const errors = checkSkills(root)
assert.equal(errors.length, 2)
assert(
errors.some((error) => error.startsWith('.agents/skills/sample/SKILL.md:'))
)
assert(
errors.some((error) =>
error.startsWith('.agents/skills/sample/agents/openai.yaml:')
)
)
})

test('reports missing links and literal resources while ignoring examples and remote URLs', (context) => {
const { root, write } = fixture(context)
write(
'.agents/skills/sample/references/guide.md',
'[Remote](https://example.com)\n[Section](#section)\n```md\n[Example](placeholder.md)\n```\n[Missing](missing.md)\n'
)
let errors = checkSkills(root)
assert.equal(errors.length, 1)
assert.match(errors[0], /missing\.md/u)
write(
'.agents/skills/sample/references/guide.md',
'Run `scripts/missing.mjs`.\n'
)
errors = checkSkills(root)
assert.equal(errors.length, 1)
assert.match(errors[0], /scripts\/missing\.mjs/u)
})

test('reports a mismatched skill name, invalid prompt, and unresolved AGENTS routing', (context) => {
const { root, write } = fixture(context)
write(
'.agents/skills/sample/SKILL.md',
'---\nname: another\ndescription: Example skill\n---\n'
)
write(
'.agents/skills/sample/agents/openai.yaml',
'interface:\n default_prompt: "Use $another."\n'
)
write('AGENTS.md', 'Use $missing.\n')
const errors = checkSkills(root)
assert.equal(errors.length, 3)
assert(errors.some((error) => error.startsWith('AGENTS.md:')))
})
56 changes: 56 additions & 0 deletions .agents/skills/ui-kit-component-docs/SKILL.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
---
name: ui-kit-component-docs
description: >
Write or shorten Russian UI Kit component Markdown and public API JSDoc,
excluding task descriptions, migration reports, and release notes.
---

# Документация компонентов Prime UI Kit

Сверь публичные props, экспорты, defaults, примеры и поведение с исходниками,
тестами и Storybook. За образец бери актуальные Tag, Badge, Button или Input.
Пример другой ветки читай через `git show`, не переключая рабочую область.

## Markdown

Создавай `<Component>.md` рядом с компонентом. Используй только нужные разделы:

1. Название и одно предложение о назначении.
2. `Использование` — минимальный пример с публичным импортом пакета.
3. `Props` — сначала назначение собственного prop, затем существенные варианты,
defaults (включая встроенные иконки) и ограничения сочетаний. Добавь
относительную ссылку на публичный тип, для вложенного компонента — на его
тип.
4. `Доступность` — как получается доступное имя, роли и ответственность
потребителя. Если разработчику нужно задать имя или учесть другой нюанс,
добавь короткую рекомендацию с условием её применения. При необходимости
поясни интерактивного родителя и масштаб шрифта.
5. `Макет` — точная известная ссылка на компонент в Figma.

Стандартные RN props не перечисляй, особое поведение объясняй по месту. Сначала
опиши назначение prop, затем особенности a11y. `accessibilityLabel` описывай в
доступности: различай автоматическое озвучивание компонента и добавление его
смысла потребителем в доступное имя родителя.

## JSDoc И Краткость

Для изменяемого публичного компонента и его собственных props опиши назначение,
смысл callback, controlled-поведение, defaults и существенные ограничения.
Рекомендацию для потребителя повтори в JSDoc соответствующего prop или
компонента, чтобы она была видна при использовании API в редакторе. Добавляй
точную известную Figma-ссылку через `@see`. Для deprecated API укажи замену без
неподтверждённого срока удаления.

Пиши кратко по-русски, без повторов, внутренних функций, токенов, тестов и
хронологии. Сохраняй подтверждённые ограничения: сокращение текста, условия
label/caption, обязательную иконку и доступное имя для iconOnly. Не обещай
непроверенные платформенные возможности.

Совместимость и миграцию не включай в документацию компонента. Если запрошены,
выдай отдельно в чате. README и ссылки из Storybook меняй только по запросу,
сохраняя существующий формат.

## Проверка

Проверь относительные ссылки и точный Figma-узел. Запусти целевой Prettier и
`git diff --check`; остальные проверки и отчёт — по `AGENTS.md`.
3 changes: 3 additions & 0 deletions .agents/skills/ui-kit-component-docs/agents/openai.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
interface:
display_name: 'UI Kit Component Docs'
short_description: 'Write Russian component Markdown and API JSDoc'
54 changes: 54 additions & 0 deletions .agents/skills/ui-kit-figma/SKILL.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
---
name: ui-kit-figma
description: >
Inspect Figma components, sync UI Kit implementations and theme-token
bindings, or update exact design links. Read-only toward Figma.
---

# UI Kit Figma

Use the node and file/branch identity from the supplied link; do not substitute
the current selection. Use the Figma design-to-code skill before design-context
calls. Implementation uses existing tokens; token changes or regeneration
require confirmation under `AGENTS.md`.

## Inspect A Design

For identification, description, or a screenshot, inspect the explicit node and
use structural metadata as needed. Return the actual image when a screenshot is
requested. Distinguish visible facts, metadata-backed properties, and behavioral
inference; a static frame does not prove interaction behavior. Skip token
mapping, implementation, tests, and story edits for inspection-only requests.
Report unavailable evidence without inventing results.

## Component Synchronization

1. Inspect the component source, public types and barrels, nearest tests and
stories, and relevant files under `src/theme/tokens`.
2. Read [token-mapping.md](references/token-mapping.md). Call Figma design
context on the exact component or variant frame. If a page or section returns
sparse context, use metadata only to locate the inner frame, then call design
context on that frame.
3. Read variable definitions for the target frame and map each relevant Figma
variable to the existing runtime theme path.
4. Implement the smallest compatible source change, following the nearest
component pattern and root `AGENTS.md`. Use `ui-kit-public-api` when the
public contract changes.
5. Use `ui-kit-testing` for changed behavior and `ui-kit-storybook` for affected
public scenarios, controls, and device verification. Compare rendered states
with the exact frame when visual alignment is in scope. Do not use static
style assertions to prove a Figma mapping.
6. Update the component documentation link when its exact Figma frame is known.
7. Run the verification required by root `AGENTS.md`.

## Links Only

- Link a component to its exact Figma component or variant frame, not merely the
file, page, or broad section containing it.
- In a bulk link update, inventory the component documentation first. Update
only confidently matched frames and keep unresolved components explicit.
- Use supplied exact links directly; inspect Figma metadata to resolve missing
frames. Fetch design context only if metadata cannot establish the match.
- Skip token mapping, implementation, tests, and story changes unless requested.
Validate links and document formatting; report updated and unresolved links
separately, including before a requested commit.
6 changes: 6 additions & 0 deletions .agents/skills/ui-kit-figma/agents/openai.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
interface:
display_name: 'UI Kit Figma'
short_description: 'Inspect Figma designs and sync UI Kit components'
default_prompt:
'Use $ui-kit-figma to inspect a design or sync a UI Kit component from its
Figma specification.'
18 changes: 18 additions & 0 deletions .agents/skills/ui-kit-figma/references/token-mapping.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
# Token Mapping

- Treat Figma variable bindings as the source of token intent. Resolved pixels
and colors are inspection data, not values to copy into source.
- Use `design-tokens/input/tokens.json` as the latest designer export and
`src/theme/tokens/**` as generated output. Follow `AGENTS.md` for explicit
confirmation before changing token values or regenerating output; ordinary
synchronization does not grant that approval.
- Reuse existing runtime theme paths; do not hardcode resolved values when a
matching local token exists.
- Prefer a component token when Figma explicitly binds that property to a
component variable. Use a semantic token when the intent is semantic or no
component binding exists.
- If an exact value has no matching token, report the gap and the part that
cannot be matched with current tokens. Do not hardcode it, silently substitute
an approximate token, or change token data without the required confirmation.
- Apply severity, size, state, and theme bindings to every affected layer: text,
background, border, icon, and shape, not only the outer container.
Loading
Loading