@sberbusiness/triplex-next-mcp-server 1.50.0-beta → 1.53.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +1 -0
- package/bundle/components/AlertProcess.md +6 -3
- package/bundle/components/AlertProcessSpoiler.md +216 -0
- package/bundle/components/Badge.md +4 -3
- package/bundle/components/ButtonDropdown.md +5 -3
- package/bundle/components/Carousel.md +671 -0
- package/bundle/components/CarouselExtended.md +7 -5
- package/bundle/components/CarouselIndicators.md +666 -0
- package/bundle/components/CarouselItem.md +579 -0
- package/bundle/components/CarouselNextButton.md +633 -0
- package/bundle/components/CarouselPrevButton.md +633 -0
- package/bundle/components/CarouselViewport.md +631 -0
- package/bundle/components/CheckboxTreeExtended.md +21 -7
- package/bundle/components/CheckboxTreeExtendedCheckbox.md +591 -0
- package/bundle/components/CheckboxTreeExtendedNode.md +577 -0
- package/bundle/components/Chip.md +1 -0
- package/bundle/components/ChipDatePicker.md +332 -0
- package/bundle/components/ChipDatePickerTarget.md +316 -0
- package/bundle/components/ChipMonthYearPicker.md +4 -3
- package/bundle/components/ChipMonthYearPickerTarget.md +318 -0
- package/bundle/components/ChipMultiselect.md +63 -73
- package/bundle/components/ChipSelect.md +385 -0
- package/bundle/components/ChipSelectTarget.md +388 -0
- package/bundle/components/ChipSuggest.md +10 -16
- package/bundle/components/ChipSuggestTarget.md +506 -0
- package/bundle/components/CollapsibleTree.md +2 -1
- package/bundle/components/CollapsibleTreeExtended.md +2 -1
- package/bundle/components/DateField.md +4 -2
- package/bundle/components/DatePickerExtended.md +16 -14
- package/bundle/components/DateRange.md +17 -10
- package/bundle/components/Dropdown.md +36 -63
- package/bundle/components/EmptyView.md +9 -4
- package/bundle/components/ExpandAnimation.md +9 -5
- package/bundle/components/FormField.md +1 -1
- package/bundle/components/ImageGallery.md +19 -52
- package/bundle/components/ImageGalleryExtended.md +123 -139
- package/bundle/components/ListItemControlsButtonDropdown.md +3 -2
- package/bundle/components/LoaderSmall.md +5 -4
- package/bundle/components/MonthYearRange.md +334 -0
- package/bundle/components/MultiselectField.md +81 -143
- package/bundle/components/Notification.md +2 -1
- package/bundle/components/NotificationGrouped.md +174 -0
- package/bundle/components/NumberField.md +259 -116
- package/bundle/components/OrderedList.md +149 -112
- package/bundle/components/Overlay.md +3 -2
- package/bundle/components/PageIndicators.md +306 -0
- package/bundle/components/Pagination.md +81 -3
- package/bundle/components/PaginationExtended.md +160 -0
- package/bundle/components/Portal.md +5 -2
- package/bundle/components/Puller.md +375 -0
- package/bundle/components/SMSField.md +277 -102
- package/bundle/components/SelectExtendedField.md +11 -7
- package/bundle/components/SelectField.md +7 -4
- package/bundle/components/SmartSpot.md +259 -0
- package/bundle/components/Step.md +2 -1
- package/bundle/components/Stepper.md +7 -7
- package/bundle/components/Suggest.md +7 -6
- package/bundle/components/SuggestField.md +8 -6
- package/bundle/components/TableBasic.md +12 -14
- package/bundle/components/Tooltip.md +9 -8
- package/bundle/guides/commits.md +4 -1
- package/bundle/guides/context.md +5 -5
- package/bundle/guides/stories.md +29 -21
- package/bundle/manifest.json +145 -13
- package/bundle/release-notes/1.50.0.mdx +4 -0
- package/bundle/release-notes/1.51.0.mdx +57 -0
- package/bundle/release-notes/1.52.0.mdx +55 -0
- package/bundle/release-notes/1.53.0.mdx +60 -0
- package/bundle/release-notes/1.54.0.mdx +45 -0
- package/bundle/release-notes/1.55.0.mdx +7 -0
- package/bundle/tokens.json +377 -222
- package/dist/index.js +39 -1
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
// src/index.ts
|
|
4
4
|
import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
|
|
5
|
+
import { isJSONRPCRequest } from "@modelcontextprotocol/sdk/types.js";
|
|
5
6
|
|
|
6
7
|
// src/server.ts
|
|
7
8
|
import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
|
|
@@ -617,6 +618,31 @@ function registerTools(server) {
|
|
|
617
618
|
return result.ok ? { content: [{ type: "text", text: result.text }] } : { content: [{ type: "text", text: result.text }], isError: true };
|
|
618
619
|
}
|
|
619
620
|
);
|
|
621
|
+
server.tool(
|
|
622
|
+
"get_release_notes",
|
|
623
|
+
"Release notes Triplex \u0432 \u0438\u0441\u0445\u043E\u0434\u043D\u043E\u043C MDX. \u0411\u0435\u0437 \u0430\u0440\u0433\u0443\u043C\u0435\u043D\u0442\u043E\u0432 \u0432\u043E\u0437\u0432\u0440\u0430\u0449\u0430\u0435\u0442 \u0437\u0430\u043C\u0435\u0442\u043A\u0443 \u0437\u0430 \u0432\u0435\u0440\u0441\u0438\u044E bundle.",
|
|
624
|
+
{
|
|
625
|
+
version: z.string().trim().min(1).optional().describe("\u0412\u0435\u0440\u0441\u0438\u044F Triplex, \u043D\u0430\u043F\u0440\u0438\u043C\u0435\u0440 '1.53.0'.")
|
|
626
|
+
},
|
|
627
|
+
async ({ version }) => {
|
|
628
|
+
const targetVersion = version ?? bundle.triplexVersion;
|
|
629
|
+
const note = bundle.releaseNotes.find((n) => n.version === targetVersion);
|
|
630
|
+
if (note) {
|
|
631
|
+
return { content: [{ type: "text", text: note.raw }] };
|
|
632
|
+
}
|
|
633
|
+
const availableVersions = bundle.releaseNotes.map((n) => n.version).sort((a, b) => b.localeCompare(a, "en", { numeric: true })).slice(0, 5);
|
|
634
|
+
const hint = availableVersions.length ? `\u041F\u043E\u0441\u043B\u0435\u0434\u043D\u0438\u0435 \u0434\u043E\u0441\u0442\u0443\u043F\u043D\u044B\u0435 \u0432\u0435\u0440\u0441\u0438\u0438 \u2014 ${availableVersions.join(", ")}.` : "\u0412 bundle \u043D\u0435\u0442 release notes. \u041E\u0431\u043D\u043E\u0432\u0438\u0442\u0435 \u0435\u0433\u043E \u0447\u0435\u0440\u0435\u0437 npm run fetch-bundle.";
|
|
635
|
+
return {
|
|
636
|
+
content: [
|
|
637
|
+
{
|
|
638
|
+
type: "text",
|
|
639
|
+
text: `Release notes \u0434\u043B\u044F Triplex ${targetVersion} \u043E\u0442\u0441\u0443\u0442\u0441\u0442\u0432\u0443\u044E\u0442 \u0432 bundle. ${hint}`
|
|
640
|
+
}
|
|
641
|
+
],
|
|
642
|
+
isError: true
|
|
643
|
+
};
|
|
644
|
+
}
|
|
645
|
+
);
|
|
620
646
|
server.tool(
|
|
621
647
|
"list_icons",
|
|
622
648
|
"\u0421\u043F\u0438\u0441\u043E\u043A \u0434\u043E\u0441\u0442\u0443\u043F\u043D\u044B\u0445 \u0438\u043A\u043E\u043D\u043E\u043A \u0438\u0437 @sberbusiness/icons-next. \u0418\u0441\u043F\u043E\u043B\u044C\u0437\u0443\u0439 \u043F\u0435\u0440\u0435\u0434 \u0442\u0435\u043C \u043A\u0430\u043A \u0438\u043C\u043F\u043E\u0440\u0442\u0438\u0440\u043E\u0432\u0430\u0442\u044C \u0438\u043A\u043E\u043D\u043A\u0443, \u0447\u0442\u043E\u0431\u044B \u043D\u0435 \u043F\u0440\u0438\u0434\u0443\u043C\u0430\u0442\u044C \u043D\u0435\u0441\u0443\u0449\u0435\u0441\u0442\u0432\u0443\u044E\u0449\u0435\u0435 \u0438\u043C\u044F. \u0424\u0438\u043B\u044C\u0442\u0440\u0430\u0446\u0438\u044F \u043F\u043E \u043F\u043E\u0434\u0441\u0442\u0440\u043E\u043A\u0435 \u0432 \u0438\u043C\u0435\u043D\u0438 \u0438 \u043F\u043E \u0440\u0430\u0437\u043C\u0435\u0440\u0443.",
|
|
@@ -676,9 +702,21 @@ function createServer() {
|
|
|
676
702
|
}
|
|
677
703
|
|
|
678
704
|
// src/index.ts
|
|
705
|
+
var TriplexStdioTransport = class extends StdioServerTransport {
|
|
706
|
+
async start() {
|
|
707
|
+
const handleMessage = this.onmessage;
|
|
708
|
+
this.onmessage = (message) => {
|
|
709
|
+
if (isJSONRPCRequest(message) && message.method === "tools/call" && message.params?.name === "get_release_notes" && message.params.arguments === void 0) {
|
|
710
|
+
message.params.arguments = {};
|
|
711
|
+
}
|
|
712
|
+
handleMessage?.(message);
|
|
713
|
+
};
|
|
714
|
+
await super.start();
|
|
715
|
+
}
|
|
716
|
+
};
|
|
679
717
|
async function main() {
|
|
680
718
|
const server = createServer();
|
|
681
|
-
const transport = new
|
|
719
|
+
const transport = new TriplexStdioTransport();
|
|
682
720
|
await server.connect(transport);
|
|
683
721
|
console.error("Triplex MCP Server started");
|
|
684
722
|
}
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/index.ts","../src/server.ts","../src/tools/index.ts","../src/parsers/loader.ts","../src/parsers/parseComponent.ts","../src/tools/component.ts","../src/tools/guidelines.ts","../src/tools/tokens.ts"],"sourcesContent":["import { StdioServerTransport } from \"@modelcontextprotocol/sdk/server/stdio.js\";\nimport { createServer } from \"./server.js\";\n\nasync function main() {\n const server = createServer();\n const transport = new StdioServerTransport();\n await server.connect(transport);\n console.error(\"Triplex MCP Server started\");\n}\n\nmain().catch((error) => {\n console.error(\"Failed to start server:\", error);\n process.exit(1);\n});\n","import { McpServer } from \"@modelcontextprotocol/sdk/server/mcp.js\";\nimport { registerTools } from \"./tools/index.js\";\n\nexport function createServer(): McpServer {\n const server = new McpServer({\n name: \"triplex\",\n version: \"0.1.0\",\n });\n\n registerTools(server);\n\n return server;\n}\n","import { McpServer } from \"@modelcontextprotocol/sdk/server/mcp.js\";\nimport { z } from \"zod\";\nimport { loadBundle, loadIcons } from \"../parsers/loader.js\";\nimport { buildComponentResponse } from \"./component.js\";\nimport { buildGuidelinesResponse } from \"./guidelines.js\";\nimport { buildTokensResponse } from \"./tokens.js\";\n\nexport function registerTools(server: McpServer): void {\n const bundle = loadBundle();\n const icons = loadIcons();\n const availableIconSizes = Array.from(new Set(icons.icons.map((i) => i.size))).sort(\n (a, b) => a - b,\n );\n\n server.tool(\n \"list_components\",\n \"Список всех компонентов дизайн-системы Triplex с кратким описанием и флагом ai_ready.\",\n {},\n async () => {\n const list = bundle.components.map((c) => ({\n name: c.name,\n description: c.description,\n category: c.category,\n ai_ready: c.ai_ready,\n }));\n\n return {\n content: [{ type: \"text\", text: JSON.stringify(list, null, 2) }],\n };\n },\n );\n\n server.tool(\n \"get_component\",\n \"Документация компонента. По умолчанию — компактная: назначение, props, инварианты, accessibility, один короткий пример и оглавление остального с размерами. Справочную секцию, другой пример или весь AI.md — параметром section, example или full; длинный ответ приходит порциями с подсказкой offset.\",\n {\n name: z.string().describe(\"Имя компонента, например 'Button'\"),\n section: z\n .string()\n .optional()\n .describe(\"Одна секция AI.md целиком, напр. 'Дизайн-токены' (список — в оглавлении).\"),\n example: z\n .string()\n .optional()\n .describe(\"Один пример из «Примеры использования» по имени, напр. 'States'.\"),\n full: z.boolean().optional().describe(\"Весь AI.md одним текстом, порциями.\"),\n offset: z\n .number()\n .int()\n .nonnegative()\n .optional()\n .describe(\"Смещение продолжения длинного ответа — из подсказки в конце порции.\"),\n },\n async ({ name, section, example, full, offset }) => {\n const component = bundle.components.find((c) => c.name.toLowerCase() === name.toLowerCase());\n\n if (!component) {\n return {\n content: [\n {\n type: \"text\",\n text: `Компонент \"${name}\" не найден. Используйте list_components для списка доступных компонентов.`,\n },\n ],\n isError: true,\n };\n }\n\n const result = buildComponentResponse(component, { section, example, full, offset });\n\n return result.ok\n ? { content: [{ type: \"text\", text: result.text }] }\n : { content: [{ type: \"text\", text: result.text }], isError: true };\n },\n );\n\n server.tool(\n \"get_tokens\",\n \"Дизайн-токены Triplex: пути `Группа.Токен` для ThemeProvider, значения светлой и тёмной темы, ссылки на палитру. Без аргументов — индекс групп.\",\n {\n component: z\n .string()\n .optional()\n .describe(\"Имя компонента: вернуть токены, которые он использует. Напр. 'Calendar'.\"),\n group: z\n .string()\n .optional()\n .describe(\"Имя группы токенов: вернуть всю группу целиком. Напр. 'ColorBrand'.\"),\n },\n async ({ component, group }) => {\n const result = buildTokensResponse(bundle, { component, group });\n\n return result.ok\n ? { content: [{ type: \"text\", text: JSON.stringify(result.payload, null, 2) }] }\n : { content: [{ type: \"text\", text: result.text }], isError: true };\n },\n );\n\n server.tool(\n \"get_guidelines\",\n \"Гайдлайны кодогенерации на Triplex для ИИ-агентов: правила TPX-G-NN — какие компоненты использовать для текстов, сетки, отступов, иконок, обвязка приложения. Прочитай перед генерацией кода по макету.\",\n {},\n async () => {\n const result = buildGuidelinesResponse(bundle);\n\n return result.ok\n ? { content: [{ type: \"text\", text: result.text }] }\n : { content: [{ type: \"text\", text: result.text }], isError: true };\n },\n );\n\n server.tool(\n \"list_icons\",\n \"Список доступных иконок из @sberbusiness/icons-next. Используй перед тем как импортировать иконку, чтобы не придумать несуществующее имя. Фильтрация по подстроке в имени и по размеру.\",\n {\n query: z\n .string()\n .optional()\n .describe(\n \"Подстрока для поиска в имени иконки (регистронезависимая). Напр. 'plus' или 'arrow'.\",\n ),\n size: z\n .number()\n .int()\n .positive()\n .optional()\n .describe(\"Размер иконки в px (см. availableSizes в ответе для доступных значений).\"),\n limit: z\n .number()\n .int()\n .positive()\n .max(500)\n .optional()\n .describe(\"Максимум иконок в ответе. По умолчанию 100.\"),\n },\n async ({ query, size, limit }) => {\n if (icons.icons.length === 0) {\n return {\n content: [\n {\n type: \"text\",\n text: \"Список иконок пуст — сервер не смог загрузить bundle/icons.json. Проверь, что 'npm run fetch-icons' отработал на этапе сборки.\",\n },\n ],\n isError: true,\n };\n }\n\n const needle = query?.trim().toLowerCase() ?? \"\";\n const max = limit ?? 100;\n\n const matched = icons.icons.filter((ic) => {\n if (size !== undefined && ic.size !== size) return false;\n if (needle && !ic.name.toLowerCase().includes(needle)) return false;\n return true;\n });\n\n const truncated = matched.length > max;\n const page = truncated ? matched.slice(0, max) : matched;\n\n const payload = {\n package: `${icons.packageName}@${icons.packageVersion}`,\n totalInBundle: icons.icons.length,\n matched: matched.length,\n returned: page.length,\n truncated,\n availableSizes: availableIconSizes,\n icons: page,\n usage: \"import { IconName } from '@sberbusiness/icons-next'; <IconName />\",\n };\n\n return {\n content: [{ type: \"text\", text: JSON.stringify(payload, null, 2) }],\n };\n },\n );\n}\n","import { existsSync, readFileSync } from \"node:fs\";\nimport { dirname, resolve } from \"node:path\";\nimport { fileURLToPath } from \"node:url\";\nimport type {\n IconsBundle,\n Manifest,\n ParsedBundle,\n RawComponent,\n TokensSection,\n} from \"../types/index.js\";\nimport { parseComponent } from \"./parseComponent.js\";\n\nconst EMPTY_BUNDLE: ParsedBundle = {\n schemaVersion: 1,\n triplexVersion: \"0.0.0\",\n generatedAt: new Date(0).toISOString(),\n components: [],\n guides: [],\n releaseNotes: [],\n tokens: null,\n};\n\nconst EMPTY_ICONS: IconsBundle = {\n schemaVersion: 1,\n packageName: \"@sberbusiness/icons-next\",\n packageVersion: \"0.0.0\",\n generatedAt: new Date(0).toISOString(),\n icons: [],\n};\n\n/**\n * Tsup bundles всю source в `dist/index.js`, поэтому относительный путь\n * src/parsers/loader.ts → bundle/... не совпадает с runtime-путём.\n * Идём вверх до ближайшего `package.json` — так корень пакета находится\n * и в dev (tsx/vitest из src/), и в prod (bundled dist/), и после npm-install.\n */\nfunction findPackageRoot(startDir: string): string {\n let dir = startDir;\n while (dir !== dirname(dir)) {\n if (existsSync(resolve(dir, \"package.json\"))) {\n return dir;\n }\n dir = dirname(dir);\n }\n throw new Error(`package.json not found above ${startDir}`);\n}\n\nconst PACKAGE_ROOT = findPackageRoot(dirname(fileURLToPath(import.meta.url)));\nconst BUNDLE_DIR = resolve(PACKAGE_ROOT, \"bundle\");\nconst MANIFEST_PATH = resolve(BUNDLE_DIR, \"manifest.json\");\nconst ICONS_PATH = resolve(BUNDLE_DIR, \"icons.json\");\n\nexport function loadIcons(): IconsBundle {\n try {\n return JSON.parse(readFileSync(ICONS_PATH, \"utf-8\")) as IconsBundle;\n } catch {\n console.error(`Failed to load icons from ${ICONS_PATH}. Run 'npm run fetch-icons' first.`);\n return EMPTY_ICONS;\n }\n}\n\n/**\n * Читает дерево дизайн-токенов. null — bundle собран до schemaVersion 2\n * (или файл не разложен): tools в этом случае работают без значений токенов.\n */\nfunction loadTokens(manifest: Manifest): TokensSection | null {\n if (!manifest.tokens) {\n return null;\n }\n\n try {\n return JSON.parse(readFileSync(resolve(BUNDLE_DIR, manifest.tokens), \"utf-8\")) as TokensSection;\n } catch {\n console.error(\n `Failed to load tokens from ${manifest.tokens}. Run 'npm run fetch-bundle' first.`,\n );\n return null;\n }\n}\n\nexport function loadBundle(): ParsedBundle {\n let manifest: Manifest;\n try {\n manifest = JSON.parse(readFileSync(MANIFEST_PATH, \"utf-8\")) as Manifest;\n } catch {\n console.error(\n `Failed to load manifest from ${MANIFEST_PATH}. Run 'npm run fetch-bundle' first.`,\n );\n return EMPTY_BUNDLE;\n }\n\n return {\n schemaVersion: manifest.schemaVersion,\n triplexVersion: manifest.triplexVersion,\n generatedAt: manifest.generatedAt,\n components: manifest.components.map((mc) => {\n const raw: RawComponent =\n mc.file !== null\n ? {\n name: mc.name,\n path: mc.path,\n raw: readFileSync(resolve(BUNDLE_DIR, mc.file), \"utf-8\"),\n examples: [],\n fallback: null,\n }\n : {\n name: mc.name,\n path: mc.path,\n raw: null,\n examples: [],\n fallback: {\n name: mc.name,\n storiesPath: mc.storiesPath ?? null,\n },\n };\n return parseComponent(raw);\n }),\n guides: manifest.guides.map((g) => ({\n topic: g.topic,\n path: g.path,\n raw: readFileSync(resolve(BUNDLE_DIR, g.file), \"utf-8\"),\n })),\n releaseNotes: manifest.releaseNotes.map((n) => ({\n version: n.version,\n path: n.path,\n raw: readFileSync(resolve(BUNDLE_DIR, n.file), \"utf-8\"),\n })),\n tokens: loadTokens(manifest),\n };\n}\n","import matter from \"gray-matter\";\nimport type { ComponentFrontmatter, ParsedComponent, RawComponent } from \"../types/index.js\";\n\nconst SECTION_HEADING_RE = /^##\\s+(.+?)\\s*$/;\n\nexport function parseComponent(raw: RawComponent): ParsedComponent {\n if (raw.raw === null) {\n const fallback = raw.fallback ?? { name: raw.name, storiesPath: null };\n return {\n name: raw.name,\n path: raw.path,\n ai_ready: false,\n category: null,\n description: null,\n figma: { file: null, node: null },\n related: [],\n tokens: [],\n stories: fallback.storiesPath,\n sections: {},\n markdown: null,\n };\n }\n\n const parsed = matter(raw.raw);\n const fm = parsed.data as ComponentFrontmatter;\n const body = parsed.content;\n const sections = extractSections(body);\n\n return {\n name: raw.name,\n path: raw.path,\n ai_ready: true,\n category: fm.category ?? null,\n description: extractDescription(sections),\n figma: {\n file: nonEmpty(fm[\"figma-file\"]),\n node: nonEmpty(fm[\"figma-node\"]),\n },\n related: Array.isArray(fm.related) ? fm.related : [],\n tokens: Array.isArray(fm.tokens) ? fm.tokens : [],\n stories: fm.stories ?? null,\n sections,\n markdown: body,\n };\n}\n\nfunction extractSections(body: string): Record<string, string> {\n const sections: Record<string, string> = {};\n let currentTitle: string | null = null;\n let buffer: string[] = [];\n\n const flush = () => {\n if (currentTitle !== null) {\n sections[currentTitle] = buffer.join(\"\\n\").trim();\n }\n };\n\n for (const line of body.split(\"\\n\")) {\n const match = SECTION_HEADING_RE.exec(line);\n if (match) {\n flush();\n currentTitle = match[1];\n buffer = [];\n } else if (currentTitle !== null) {\n buffer.push(line);\n }\n }\n flush();\n return sections;\n}\n\nfunction extractDescription(sections: Record<string, string>): string | null {\n const purpose = sections[\"Назначение\"];\n if (!purpose) {\n return null;\n }\n const firstParagraph = purpose\n .split(/\\n\\s*\\n/)\n .map((p) => p.trim())\n .find((p) => p.length > 0);\n return firstParagraph ?? null;\n}\n\nfunction nonEmpty(value: string | undefined): string | null {\n if (typeof value !== \"string\") {\n return null;\n }\n const trimmed = value.trim();\n return trimmed.length > 0 ? trimmed : null;\n}\n","/**\n * Сборка ответа tool `get_component`.\n *\n * Ответ — Markdown. Раньше tool отдавал JSON, в котором тело AI.md лежало\n * дважды (по секциям и целиком), и ответ большого компонента доходил до\n * 200 тыс. символов. Клиенты режут вывод инструмента (GigaCode — около\n * 25 тыс. символов), а дочитанный целиком ответ съедает контекст агента.\n *\n * По умолчанию ответ компактный: всё, что нужно для кода (назначение, props,\n * инварианты, accessibility и нестандартные для шаблона секции вроде «Состав»\n * или «Поведение»), один короткий пример и оглавление остального с размерами.\n * Справочные секции, остальные примеры и весь AI.md запрашиваются параметрами;\n * длинный кусок отдаётся порциями по `MAX_CHUNK` символов с подсказкой, как\n * получить продолжение.\n */\nimport type { ParsedComponent } from \"../types/index.js\";\n\n/** Параметры tool `get_component` помимо имени. `section`, `example`, `full` — взаимоисключающие. */\nexport interface ComponentQuery {\n section?: string;\n example?: string;\n full?: boolean;\n offset?: number;\n}\n\nexport type ComponentResult = { ok: true; text: string } | { ok: false; text: string };\n\n/** Максимум символов в одной порции ответа — с запасом под порог клиентов в ~25 тыс. */\nexport const MAX_CHUNK = 20_000;\n\n/**\n * Пример попадает в компактный ответ, только если он не длиннее. Порог с\n * расчётом на `Default` составного компонента: у `LightBox` он 6,2 тыс. и\n * показывает, как собираются `Content`, `Page` и `Controls`.\n */\nexport const SHORT_EXAMPLE_MAX = 6_500;\n\nexport const EXAMPLES_SECTION = \"Примеры использования\";\n\n/**\n * Справочные секции AI.md: в компактном ответе они только в оглавлении.\n * Список закрытый намеренно — секция с новым заголовком по умолчанию считается\n * частью API и попадает в ответ: лишние символы дешевле потерянного props.\n */\nexport const REFERENCE_SECTIONS: ReadonlySet<string> = new Set([\n \"Дизайн-токены\",\n \"Связанные компоненты\",\n \"Stories\",\n \"История изменений\",\n \"Файловая структура\",\n \"Ключевые особенности реализации\",\n EXAMPLES_SECTION,\n]);\n\nconst SUBSECTION_HEADING_RE = /^###\\s+(.+?)\\s*$/;\nconst FENCE_RE = /^\\s*```/;\nconst TRAILING_RULE_RE = /\\n+-{3,}\\s*$/;\n\n/** Порция длинного текста: `next` — смещение продолжения, null — текст закончился. */\nexport interface Chunk {\n body: string;\n next: number | null;\n}\n\n/**\n * Режет текст на порции не длиннее `MAX_CHUNK`, стараясь закончить порцию на\n * переводе строки — чтобы не рвать строку кода или таблицы посередине.\n */\nexport function paginate(text: string, offset: number): Chunk {\n if (text.length - offset <= MAX_CHUNK) {\n return { body: text.slice(offset), next: null };\n }\n\n const hardEnd = offset + MAX_CHUNK;\n const newline = text.lastIndexOf(\"\\n\", hardEnd - 1);\n const end = newline > offset + MAX_CHUNK / 2 ? newline + 1 : hardEnd;\n return { body: text.slice(offset, end), next: end };\n}\n\n/**\n * Подсекции `### {Заголовок}` — в «Примерах использования» это отдельные\n * примеры. Заголовки внутри блоков кода не считаются.\n */\nexport function extractSubsections(text: string): Record<string, string> {\n const result: Record<string, string> = {};\n let current: string | null = null;\n let buffer: string[] = [];\n let inFence = false;\n\n const flush = () => {\n if (current !== null) {\n result[current] = buffer.join(\"\\n\").trim();\n }\n };\n\n for (const line of text.split(\"\\n\")) {\n if (FENCE_RE.test(line)) {\n inFence = !inFence;\n }\n const match = inFence ? null : SUBSECTION_HEADING_RE.exec(line);\n if (match) {\n flush();\n current = match[1];\n buffer = [];\n } else if (current !== null) {\n buffer.push(line);\n }\n }\n flush();\n return result;\n}\n\n/** Текст секции без завершающего разделителя `---`: в AI.md им закрыта каждая секция. */\nfunction sectionText(text: string): string {\n return text.replace(TRAILING_RULE_RE, \"\").trim();\n}\n\nfunction findKey(record: Record<string, string>, wanted: string): string | undefined {\n const needle = wanted.trim().toLowerCase();\n return Object.keys(record).find((key) => key.toLowerCase() === needle);\n}\n\nfunction quoteList(names: string[]): string {\n return names.map((name) => JSON.stringify(name)).join(\", \");\n}\n\nfunction callHint(name: string, args: Record<string, unknown>): string {\n return `get_component ${JSON.stringify({ name, ...args })}`;\n}\n\n/** Строка метаданных из frontmatter: категория, связанные компоненты, Figma, токены. */\nfunction metaLine(component: ParsedComponent): string | null {\n const parts: string[] = [];\n if (component.category) {\n parts.push(`Категория: ${component.category}`);\n }\n if (component.related.length > 0) {\n parts.push(`Связанные: ${component.related.join(\", \")}`);\n }\n if (component.figma.file || component.figma.node) {\n parts.push(`Figma: ${[component.figma.file, component.figma.node].filter(Boolean).join(\", \")}`);\n }\n if (component.tokens.length > 0) {\n parts.push(\n `Токены (${component.tokens.length}): get_tokens ${JSON.stringify({ component: component.name })}`,\n );\n }\n return parts.length > 0 ? parts.join(\" · \") : null;\n}\n\n/** Короткий пример для компактного ответа: `Default`, иначе самый короткий из подходящих. */\nfunction pickShortExample(examples: Record<string, string>): string | null {\n const fitting = Object.keys(examples).filter((key) => examples[key].length <= SHORT_EXAMPLE_MAX);\n if (fitting.length === 0) {\n return null;\n }\n const byDefault = fitting.find((key) => key.toLowerCase() === \"default\");\n if (byDefault) {\n return byDefault;\n }\n return fitting.reduce((best, key) => (examples[key].length < examples[best].length ? key : best));\n}\n\nfunction buildCompact(component: ParsedComponent): string {\n const { sections } = component;\n const parts: string[] = [`# ${component.name}`];\n\n const meta = metaLine(component);\n if (meta) {\n parts.push(meta);\n }\n\n for (const [title, text] of Object.entries(sections)) {\n if (!REFERENCE_SECTIONS.has(title)) {\n parts.push(`## ${title}\\n\\n${sectionText(text)}`);\n }\n }\n\n const examples = extractSubsections(sections[EXAMPLES_SECTION] ?? \"\");\n const shown = pickShortExample(examples);\n if (shown) {\n parts.push(`## Пример: ${shown}\\n\\n${examples[shown]}`);\n }\n\n const moreSections = Object.keys(sections)\n .filter((title) => REFERENCE_SECTIONS.has(title) && title !== EXAMPLES_SECTION)\n .map((title) => `${JSON.stringify(title)} ${sectionText(sections[title]).length}`);\n const moreExamples = Object.keys(examples)\n .filter((title) => title !== shown)\n .map((title) => `${JSON.stringify(title)} ${examples[title].length}`);\n\n const more = [\n \"## Ещё\\n\",\n \"Это компактный ответ. Остальное — тем же get_component, одним из параметров (размер в символах):\",\n ];\n if (moreSections.length > 0) {\n more.push(`- section: ${moreSections.join(\", \")}`);\n }\n if (moreExamples.length > 0) {\n more.push(`- example: ${moreExamples.join(\", \")}`);\n }\n more.push(`- full: true — весь AI.md, ${(component.markdown ?? \"\").length}`);\n parts.push(more.join(\"\\n\"));\n\n return parts.join(\"\\n\\n\");\n}\n\nfunction buildFallback(component: ParsedComponent): string {\n const stories = component.stories ? ` Stories: \\`${component.stories}\\`.` : \"\";\n return `# ${component.name}\\n\\nAI-документации у компонента нет (ai_ready: false).${stories}`;\n}\n\n/** Выбранный параметрами кусок AI.md или текст ошибки. */\nfunction selectPiece(\n component: ParsedComponent,\n query: ComponentQuery,\n): { ok: true; text: string; args: Record<string, unknown> } | { ok: false; text: string } {\n const { sections } = component;\n\n if (query.section !== undefined) {\n const key = findKey(sections, query.section);\n if (key === undefined) {\n return {\n ok: false,\n text: `Секции ${JSON.stringify(query.section)} у ${component.name} нет. Есть: ${quoteList(Object.keys(sections))}.`,\n };\n }\n return { ok: true, text: `## ${key}\\n\\n${sectionText(sections[key])}`, args: { section: key } };\n }\n\n if (query.example !== undefined) {\n const examples = extractSubsections(sections[EXAMPLES_SECTION] ?? \"\");\n const key = findKey(examples, query.example);\n if (key === undefined) {\n const names = Object.keys(examples);\n return {\n ok: false,\n text:\n names.length > 0\n ? `Примера ${JSON.stringify(query.example)} у ${component.name} нет. Есть: ${quoteList(names)}.`\n : `У ${component.name} нет секции «${EXAMPLES_SECTION}».`,\n };\n }\n return { ok: true, text: `### ${key}\\n\\n${examples[key]}`, args: { example: key } };\n }\n\n if (query.full) {\n const meta = metaLine(component);\n const body = component.markdown ?? \"\";\n return { ok: true, text: meta ? `${meta}\\n\\n${body}` : body, args: { full: true } };\n }\n\n return { ok: true, text: buildCompact(component), args: {} };\n}\n\nexport function buildComponentResponse(\n component: ParsedComponent,\n query: ComponentQuery = {},\n): ComponentResult {\n const selectors = [query.section !== undefined, query.example !== undefined, query.full === true];\n if (selectors.filter(Boolean).length > 1) {\n return { ok: false, text: \"Укажи не больше одного из параметров: section, example, full.\" };\n }\n\n if (!component.ai_ready) {\n return { ok: true, text: buildFallback(component) };\n }\n\n const piece = selectPiece(component, query);\n if (!piece.ok) {\n return piece;\n }\n\n const offset = query.offset ?? 0;\n if (offset > 0 && offset >= piece.text.length) {\n return {\n ok: false,\n text: `offset ${offset} за концом ответа: в нём ${piece.text.length} символов.`,\n };\n }\n\n const chunk = paginate(piece.text, offset);\n const end = offset + chunk.body.length;\n const lines: string[] = [];\n if (offset > 0) {\n lines.push(`— Продолжение: символы ${offset}–${end} из ${piece.text.length} —\\n`);\n }\n lines.push(chunk.body);\n if (chunk.next !== null) {\n lines.push(\n `\\n— Показаны символы ${offset}–${end} из ${piece.text.length}. ` +\n `Продолжение: ${callHint(component.name, { ...piece.args, offset: chunk.next })} —`,\n );\n }\n return { ok: true, text: lines.join(\"\\n\") };\n}\n","/**\n * Сборка ответа tool `get_guidelines`.\n *\n * Гайдлайны кодогенерации (`docs/mcp/guidelines.md` в triplex-next, правила\n * `TPX-G-NN`) приезжают через bundle как guide с топиком `guidelines` —\n * начиная с triplex-next 1.45.0. На более старом bundle топика нет: сервер\n * обязан работать и в этом случае, отвечая внятной ошибкой, а не падая.\n */\nimport type { ParsedBundle } from \"../types/index.js\";\n\nexport const GUIDELINES_TOPIC = \"guidelines\";\n\nexport type GuidelinesResult = { ok: true; text: string } | { ok: false; text: string };\n\nexport function buildGuidelinesResponse(bundle: ParsedBundle): GuidelinesResult {\n const guide = bundle.guides.find((g) => g.topic === GUIDELINES_TOPIC);\n\n if (!guide) {\n return {\n ok: false,\n text:\n `Bundle собран из triplex-next ${bundle.triplexVersion} и гайдлайнов не содержит — ` +\n \"они поставляются начиная с 1.45.0. Обновите bundle: npm run fetch-bundle.\",\n };\n }\n\n return { ok: true, text: guide.raw };\n}\n","/**\n * Сборка ответа tool `get_tokens`.\n *\n * Токены Triplex адресуются путём `Группа.Токен` — ровно в этом виде они\n * передаются в `ThemeProvider` через prop `tokens`. CSS-переменные\n * `--triplex-next-*` публичным API не являются: на сборке библиотеки к имени\n * дописывается версия пакета.\n *\n * Дерево токенов приходит в bundle начиная с `schemaVersion: 2`. Для более\n * старых bundle доступны только пути из frontmatter AI.md — ответ в этом случае\n * помечается `note`, а сервер продолжает работать.\n */\nimport type { ParsedBundle, TokenEntry, TokensSection } from \"../types/index.js\";\n\n/** Фильтры tool `get_tokens`. Оба необязательны, `group` имеет приоритет. */\nexport interface TokensQuery {\n component?: string;\n group?: string;\n}\n\nexport type TokensResult = { ok: true; payload: unknown } | { ok: false; text: string };\n\nexport const LEGACY_NOTE =\n \"Bundle собран до schemaVersion 2 и значений токенов не содержит — доступны только пути. Обновите bundle: npm run fetch-bundle.\";\n\n/** Как потребитель переопределяет токен: единственный публичный способ. */\nfunction howToOverride(group: string) {\n return {\n api: \"<ThemeProvider tokens={...}> из @sberbusiness/triplex-next\",\n example: [\n \"const TOKENS = {\",\n ` ${group}: {`,\n ' <Токен>: {value: \"#FFFFFF\"}, // своё значение',\n ' <Другой>: {ref: \"ColorBrand.50\"}, // ссылка на core-токен',\n \" },\",\n \"};\",\n \"\",\n \"<ThemeProvider tokens={TOKENS} scopeRef={scopeRef}>…</ThemeProvider>\",\n ].join(\"\\n\"),\n notes: [\n \"Объект tokens плоский: группы лежат на верхнем уровне, вложенности core/components нет.\",\n \"Одним объектом можно переопределить несколько групп сразу — и core, и компонентные.\",\n \"ref указывает только на core-токены (refable: true).\",\n \"tokens сравнивается по ссылке — выносите объект из рендера.\",\n \"Переопределение действует внутри элемента из scopeRef.\",\n ],\n };\n}\n\n/** Внутренний слой: css-переменные с версией пакета в имени. */\nfunction internalNote(section: TokensSection) {\n return {\n cssVarPattern: section.internal.cssVarPattern,\n note: \"Внутренняя реализация: в собранном пакете к имени переменной добавляется версия, поэтому в коде потребителя использовать её нельзя.\",\n };\n}\n\n/** Core-токены, на которые ссылаются переданные токены. */\nfunction coreTokensUsed(tokens: TokenEntry[]): string[] {\n const refs = tokens.flatMap((token) =>\n [token.light.ref, token.dark.ref].filter((ref): ref is string => ref !== undefined),\n );\n\n return [...new Set(refs)].sort();\n}\n\n/** Индекс групп: имя → число токенов. Полное дерево слишком велико для одного ответа. */\nfunction groupIndex(section: TokensSection, kind: \"core\" | \"component\"): Record<string, number> {\n return Object.fromEntries(\n Object.entries(section.groups)\n .filter(([, group]) => group.kind === kind)\n .map(([name, group]) => [name, Object.keys(group.tokens).length]),\n );\n}\n\nfunction byGroup(section: TokensSection, group: string): TokensResult {\n const name = Object.keys(section.groups).find((key) => key.toLowerCase() === group.toLowerCase());\n\n if (name === undefined) {\n return {\n ok: false,\n text: `Группа токенов \"${group}\" не найдена. Список групп: get_tokens() без аргументов.`,\n };\n }\n\n const entry = section.groups[name];\n\n return {\n ok: true,\n payload: {\n group: name,\n kind: entry.kind,\n refable: entry.refable,\n tokenCount: Object.keys(entry.tokens).length,\n howToOverride: howToOverride(name),\n tokens: Object.values(entry.tokens),\n internal: internalNote(section),\n },\n };\n}\n\nfunction byComponent(\n bundle: ParsedBundle,\n section: TokensSection | null,\n component: string,\n): TokensResult {\n const found = bundle.components.find((c) => c.name.toLowerCase() === component.toLowerCase());\n\n if (!found) {\n return {\n ok: false,\n text: `Компонент \"${component}\" не найден. Используйте list_components для списка доступных компонентов.`,\n };\n }\n\n if (section === null) {\n return {\n ok: true,\n payload: { component: found.name, tokens: found.tokens, note: LEGACY_NOTE },\n };\n }\n\n // Компонент может использовать токены нескольких групп: например, поле выбора\n // красится токенами FormField, Dropdown и DropdownList сразу.\n const resolved = found.tokens.map((path) => {\n const [group, token] = path.split(\".\");\n\n return { path, entry: section.groups[group]?.tokens[token] };\n });\n const known = resolved\n .map(({ entry }) => entry)\n .filter((entry): entry is TokenEntry => entry !== undefined);\n const unknown = resolved.filter(({ entry }) => entry === undefined).map(({ path }) => path);\n const groups = [...new Set(known.map((token) => token.path.split(\".\")[0]))];\n\n return {\n ok: true,\n payload: {\n component: found.name,\n groups,\n tokenCount: known.length,\n howToOverride: howToOverride(groups[0] ?? \"Группа\"),\n tokens: known,\n // Палитра, на которую ссылаются токены компонента: перекрасив core-токен,\n // потребитель меняет вид всех компонентов, которые на него ссылаются.\n coreTokensUsed: coreTokensUsed(known),\n ...(unknown.length ? { unknownTokens: unknown } : {}),\n internal: internalNote(section),\n },\n };\n}\n\n/** Собирает ответ `get_tokens` по фильтрам. Без фильтров возвращает индекс групп. */\nexport function buildTokensResponse(bundle: ParsedBundle, query: TokensQuery): TokensResult {\n const section = bundle.tokens;\n\n if (query.group !== undefined) {\n return section === null ? { ok: false, text: LEGACY_NOTE } : byGroup(section, query.group);\n }\n\n if (query.component !== undefined) {\n return byComponent(bundle, section, query.component);\n }\n\n if (section === null) {\n return {\n ok: true,\n payload: {\n note: LEGACY_NOTE,\n components: bundle.components\n .filter((c) => c.tokens.length > 0)\n .map((c) => ({ component: c.name, tokens: c.tokens })),\n },\n };\n }\n\n return {\n ok: true,\n payload: {\n triplexVersion: bundle.triplexVersion,\n overridePath: section.overridePath,\n core: {\n description: 'Палитра и примитивы. Ссылки { ref: \"ColorBrand.50\" } резолвятся сюда.',\n groups: groupIndex(section, \"core\"),\n },\n components: { groups: groupIndex(section, \"component\") },\n hint: 'Полные данные: get_tokens({ component: \"Calendar\" }) или get_tokens({ group: \"ColorBrand\" }).',\n },\n };\n}\n"],"mappings":"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","names":[]}
|
|
1
|
+
{"version":3,"sources":["../src/index.ts","../src/server.ts","../src/tools/index.ts","../src/parsers/loader.ts","../src/parsers/parseComponent.ts","../src/tools/component.ts","../src/tools/guidelines.ts","../src/tools/tokens.ts"],"sourcesContent":["import { StdioServerTransport } from \"@modelcontextprotocol/sdk/server/stdio.js\";\nimport { isJSONRPCRequest } from \"@modelcontextprotocol/sdk/types.js\";\nimport { createServer } from \"./server.js\";\n\nclass TriplexStdioTransport extends StdioServerTransport {\n override async start(): Promise<void> {\n const handleMessage = this.onmessage;\n this.onmessage = (message) => {\n // SDK 1.x rejects omitted arguments before invoking a tool with optional fields.\n // https://github.com/modelcontextprotocol/typescript-sdk/issues/1869\n if (\n isJSONRPCRequest(message) &&\n message.method === \"tools/call\" &&\n message.params?.name === \"get_release_notes\" &&\n message.params.arguments === undefined\n ) {\n message.params.arguments = {};\n }\n handleMessage?.(message);\n };\n await super.start();\n }\n}\n\nasync function main() {\n const server = createServer();\n const transport = new TriplexStdioTransport();\n await server.connect(transport);\n console.error(\"Triplex MCP Server started\");\n}\n\nmain().catch((error) => {\n console.error(\"Failed to start server:\", error);\n process.exit(1);\n});\n","import { McpServer } from \"@modelcontextprotocol/sdk/server/mcp.js\";\nimport { registerTools } from \"./tools/index.js\";\n\nexport function createServer(): McpServer {\n const server = new McpServer({\n name: \"triplex\",\n version: \"0.1.0\",\n });\n\n registerTools(server);\n\n return server;\n}\n","import { McpServer } from \"@modelcontextprotocol/sdk/server/mcp.js\";\nimport { z } from \"zod\";\nimport { loadBundle, loadIcons } from \"../parsers/loader.js\";\nimport { buildComponentResponse } from \"./component.js\";\nimport { buildGuidelinesResponse } from \"./guidelines.js\";\nimport { buildTokensResponse } from \"./tokens.js\";\n\nexport function registerTools(server: McpServer): void {\n const bundle = loadBundle();\n const icons = loadIcons();\n const availableIconSizes = Array.from(new Set(icons.icons.map((i) => i.size))).sort(\n (a, b) => a - b,\n );\n\n server.tool(\n \"list_components\",\n \"Список всех компонентов дизайн-системы Triplex с кратким описанием и флагом ai_ready.\",\n {},\n async () => {\n const list = bundle.components.map((c) => ({\n name: c.name,\n description: c.description,\n category: c.category,\n ai_ready: c.ai_ready,\n }));\n\n return {\n content: [{ type: \"text\", text: JSON.stringify(list, null, 2) }],\n };\n },\n );\n\n server.tool(\n \"get_component\",\n \"Документация компонента. По умолчанию — компактная: назначение, props, инварианты, accessibility, один короткий пример и оглавление остального с размерами. Справочную секцию, другой пример или весь AI.md — параметром section, example или full; длинный ответ приходит порциями с подсказкой offset.\",\n {\n name: z.string().describe(\"Имя компонента, например 'Button'\"),\n section: z\n .string()\n .optional()\n .describe(\"Одна секция AI.md целиком, напр. 'Дизайн-токены' (список — в оглавлении).\"),\n example: z\n .string()\n .optional()\n .describe(\"Один пример из «Примеры использования» по имени, напр. 'States'.\"),\n full: z.boolean().optional().describe(\"Весь AI.md одним текстом, порциями.\"),\n offset: z\n .number()\n .int()\n .nonnegative()\n .optional()\n .describe(\"Смещение продолжения длинного ответа — из подсказки в конце порции.\"),\n },\n async ({ name, section, example, full, offset }) => {\n const component = bundle.components.find((c) => c.name.toLowerCase() === name.toLowerCase());\n\n if (!component) {\n return {\n content: [\n {\n type: \"text\",\n text: `Компонент \"${name}\" не найден. Используйте list_components для списка доступных компонентов.`,\n },\n ],\n isError: true,\n };\n }\n\n const result = buildComponentResponse(component, { section, example, full, offset });\n\n return result.ok\n ? { content: [{ type: \"text\", text: result.text }] }\n : { content: [{ type: \"text\", text: result.text }], isError: true };\n },\n );\n\n server.tool(\n \"get_tokens\",\n \"Дизайн-токены Triplex: пути `Группа.Токен` для ThemeProvider, значения светлой и тёмной темы, ссылки на палитру. Без аргументов — индекс групп.\",\n {\n component: z\n .string()\n .optional()\n .describe(\"Имя компонента: вернуть токены, которые он использует. Напр. 'Calendar'.\"),\n group: z\n .string()\n .optional()\n .describe(\"Имя группы токенов: вернуть всю группу целиком. Напр. 'ColorBrand'.\"),\n },\n async ({ component, group }) => {\n const result = buildTokensResponse(bundle, { component, group });\n\n return result.ok\n ? { content: [{ type: \"text\", text: JSON.stringify(result.payload, null, 2) }] }\n : { content: [{ type: \"text\", text: result.text }], isError: true };\n },\n );\n\n server.tool(\n \"get_guidelines\",\n \"Гайдлайны кодогенерации на Triplex для ИИ-агентов: правила TPX-G-NN — какие компоненты использовать для текстов, сетки, отступов, иконок, обвязка приложения. Прочитай перед генерацией кода по макету.\",\n {},\n async () => {\n const result = buildGuidelinesResponse(bundle);\n\n return result.ok\n ? { content: [{ type: \"text\", text: result.text }] }\n : { content: [{ type: \"text\", text: result.text }], isError: true };\n },\n );\n\n server.tool(\n \"get_release_notes\",\n \"Release notes Triplex в исходном MDX. Без аргументов возвращает заметку за версию bundle.\",\n {\n version: z.string().trim().min(1).optional().describe(\"Версия Triplex, например '1.53.0'.\"),\n },\n async ({ version }) => {\n const targetVersion = version ?? bundle.triplexVersion;\n const note = bundle.releaseNotes.find((n) => n.version === targetVersion);\n\n if (note) {\n return { content: [{ type: \"text\", text: note.raw }] };\n }\n\n const availableVersions = bundle.releaseNotes\n .map((n) => n.version)\n .sort((a, b) => b.localeCompare(a, \"en\", { numeric: true }))\n .slice(0, 5);\n const hint = availableVersions.length\n ? `Последние доступные версии — ${availableVersions.join(\", \")}.`\n : \"В bundle нет release notes. Обновите его через npm run fetch-bundle.\";\n\n return {\n content: [\n {\n type: \"text\",\n text: `Release notes для Triplex ${targetVersion} отсутствуют в bundle. ${hint}`,\n },\n ],\n isError: true,\n };\n },\n );\n\n server.tool(\n \"list_icons\",\n \"Список доступных иконок из @sberbusiness/icons-next. Используй перед тем как импортировать иконку, чтобы не придумать несуществующее имя. Фильтрация по подстроке в имени и по размеру.\",\n {\n query: z\n .string()\n .optional()\n .describe(\n \"Подстрока для поиска в имени иконки (регистронезависимая). Напр. 'plus' или 'arrow'.\",\n ),\n size: z\n .number()\n .int()\n .positive()\n .optional()\n .describe(\"Размер иконки в px (см. availableSizes в ответе для доступных значений).\"),\n limit: z\n .number()\n .int()\n .positive()\n .max(500)\n .optional()\n .describe(\"Максимум иконок в ответе. По умолчанию 100.\"),\n },\n async ({ query, size, limit }) => {\n if (icons.icons.length === 0) {\n return {\n content: [\n {\n type: \"text\",\n text: \"Список иконок пуст — сервер не смог загрузить bundle/icons.json. Проверь, что 'npm run fetch-icons' отработал на этапе сборки.\",\n },\n ],\n isError: true,\n };\n }\n\n const needle = query?.trim().toLowerCase() ?? \"\";\n const max = limit ?? 100;\n\n const matched = icons.icons.filter((ic) => {\n if (size !== undefined && ic.size !== size) return false;\n if (needle && !ic.name.toLowerCase().includes(needle)) return false;\n return true;\n });\n\n const truncated = matched.length > max;\n const page = truncated ? matched.slice(0, max) : matched;\n\n const payload = {\n package: `${icons.packageName}@${icons.packageVersion}`,\n totalInBundle: icons.icons.length,\n matched: matched.length,\n returned: page.length,\n truncated,\n availableSizes: availableIconSizes,\n icons: page,\n usage: \"import { IconName } from '@sberbusiness/icons-next'; <IconName />\",\n };\n\n return {\n content: [{ type: \"text\", text: JSON.stringify(payload, null, 2) }],\n };\n },\n );\n}\n","import { existsSync, readFileSync } from \"node:fs\";\nimport { dirname, resolve } from \"node:path\";\nimport { fileURLToPath } from \"node:url\";\nimport type {\n IconsBundle,\n Manifest,\n ParsedBundle,\n RawComponent,\n TokensSection,\n} from \"../types/index.js\";\nimport { parseComponent } from \"./parseComponent.js\";\n\nconst EMPTY_BUNDLE: ParsedBundle = {\n schemaVersion: 1,\n triplexVersion: \"0.0.0\",\n generatedAt: new Date(0).toISOString(),\n components: [],\n guides: [],\n releaseNotes: [],\n tokens: null,\n};\n\nconst EMPTY_ICONS: IconsBundle = {\n schemaVersion: 1,\n packageName: \"@sberbusiness/icons-next\",\n packageVersion: \"0.0.0\",\n generatedAt: new Date(0).toISOString(),\n icons: [],\n};\n\n/**\n * Tsup bundles всю source в `dist/index.js`, поэтому относительный путь\n * src/parsers/loader.ts → bundle/... не совпадает с runtime-путём.\n * Идём вверх до ближайшего `package.json` — так корень пакета находится\n * и в dev (tsx/vitest из src/), и в prod (bundled dist/), и после npm-install.\n */\nfunction findPackageRoot(startDir: string): string {\n let dir = startDir;\n while (dir !== dirname(dir)) {\n if (existsSync(resolve(dir, \"package.json\"))) {\n return dir;\n }\n dir = dirname(dir);\n }\n throw new Error(`package.json not found above ${startDir}`);\n}\n\nconst PACKAGE_ROOT = findPackageRoot(dirname(fileURLToPath(import.meta.url)));\nconst BUNDLE_DIR = resolve(PACKAGE_ROOT, \"bundle\");\nconst MANIFEST_PATH = resolve(BUNDLE_DIR, \"manifest.json\");\nconst ICONS_PATH = resolve(BUNDLE_DIR, \"icons.json\");\n\nexport function loadIcons(): IconsBundle {\n try {\n return JSON.parse(readFileSync(ICONS_PATH, \"utf-8\")) as IconsBundle;\n } catch {\n console.error(`Failed to load icons from ${ICONS_PATH}. Run 'npm run fetch-icons' first.`);\n return EMPTY_ICONS;\n }\n}\n\n/**\n * Читает дерево дизайн-токенов. null — bundle собран до schemaVersion 2\n * (или файл не разложен): tools в этом случае работают без значений токенов.\n */\nfunction loadTokens(manifest: Manifest): TokensSection | null {\n if (!manifest.tokens) {\n return null;\n }\n\n try {\n return JSON.parse(readFileSync(resolve(BUNDLE_DIR, manifest.tokens), \"utf-8\")) as TokensSection;\n } catch {\n console.error(\n `Failed to load tokens from ${manifest.tokens}. Run 'npm run fetch-bundle' first.`,\n );\n return null;\n }\n}\n\nexport function loadBundle(): ParsedBundle {\n let manifest: Manifest;\n try {\n manifest = JSON.parse(readFileSync(MANIFEST_PATH, \"utf-8\")) as Manifest;\n } catch {\n console.error(\n `Failed to load manifest from ${MANIFEST_PATH}. Run 'npm run fetch-bundle' first.`,\n );\n return EMPTY_BUNDLE;\n }\n\n return {\n schemaVersion: manifest.schemaVersion,\n triplexVersion: manifest.triplexVersion,\n generatedAt: manifest.generatedAt,\n components: manifest.components.map((mc) => {\n const raw: RawComponent =\n mc.file !== null\n ? {\n name: mc.name,\n path: mc.path,\n raw: readFileSync(resolve(BUNDLE_DIR, mc.file), \"utf-8\"),\n examples: [],\n fallback: null,\n }\n : {\n name: mc.name,\n path: mc.path,\n raw: null,\n examples: [],\n fallback: {\n name: mc.name,\n storiesPath: mc.storiesPath ?? null,\n },\n };\n return parseComponent(raw);\n }),\n guides: manifest.guides.map((g) => ({\n topic: g.topic,\n path: g.path,\n raw: readFileSync(resolve(BUNDLE_DIR, g.file), \"utf-8\"),\n })),\n releaseNotes: manifest.releaseNotes.map((n) => ({\n version: n.version,\n path: n.path,\n raw: readFileSync(resolve(BUNDLE_DIR, n.file), \"utf-8\"),\n })),\n tokens: loadTokens(manifest),\n };\n}\n","import matter from \"gray-matter\";\nimport type { ComponentFrontmatter, ParsedComponent, RawComponent } from \"../types/index.js\";\n\nconst SECTION_HEADING_RE = /^##\\s+(.+?)\\s*$/;\n\nexport function parseComponent(raw: RawComponent): ParsedComponent {\n if (raw.raw === null) {\n const fallback = raw.fallback ?? { name: raw.name, storiesPath: null };\n return {\n name: raw.name,\n path: raw.path,\n ai_ready: false,\n category: null,\n description: null,\n figma: { file: null, node: null },\n related: [],\n tokens: [],\n stories: fallback.storiesPath,\n sections: {},\n markdown: null,\n };\n }\n\n const parsed = matter(raw.raw);\n const fm = parsed.data as ComponentFrontmatter;\n const body = parsed.content;\n const sections = extractSections(body);\n\n return {\n name: raw.name,\n path: raw.path,\n ai_ready: true,\n category: fm.category ?? null,\n description: extractDescription(sections),\n figma: {\n file: nonEmpty(fm[\"figma-file\"]),\n node: nonEmpty(fm[\"figma-node\"]),\n },\n related: Array.isArray(fm.related) ? fm.related : [],\n tokens: Array.isArray(fm.tokens) ? fm.tokens : [],\n stories: fm.stories ?? null,\n sections,\n markdown: body,\n };\n}\n\nfunction extractSections(body: string): Record<string, string> {\n const sections: Record<string, string> = {};\n let currentTitle: string | null = null;\n let buffer: string[] = [];\n\n const flush = () => {\n if (currentTitle !== null) {\n sections[currentTitle] = buffer.join(\"\\n\").trim();\n }\n };\n\n for (const line of body.split(\"\\n\")) {\n const match = SECTION_HEADING_RE.exec(line);\n if (match) {\n flush();\n currentTitle = match[1];\n buffer = [];\n } else if (currentTitle !== null) {\n buffer.push(line);\n }\n }\n flush();\n return sections;\n}\n\nfunction extractDescription(sections: Record<string, string>): string | null {\n const purpose = sections[\"Назначение\"];\n if (!purpose) {\n return null;\n }\n const firstParagraph = purpose\n .split(/\\n\\s*\\n/)\n .map((p) => p.trim())\n .find((p) => p.length > 0);\n return firstParagraph ?? null;\n}\n\nfunction nonEmpty(value: string | undefined): string | null {\n if (typeof value !== \"string\") {\n return null;\n }\n const trimmed = value.trim();\n return trimmed.length > 0 ? trimmed : null;\n}\n","/**\n * Сборка ответа tool `get_component`.\n *\n * Ответ — Markdown. Раньше tool отдавал JSON, в котором тело AI.md лежало\n * дважды (по секциям и целиком), и ответ большого компонента доходил до\n * 200 тыс. символов. Клиенты режут вывод инструмента (GigaCode — около\n * 25 тыс. символов), а дочитанный целиком ответ съедает контекст агента.\n *\n * По умолчанию ответ компактный: всё, что нужно для кода (назначение, props,\n * инварианты, accessibility и нестандартные для шаблона секции вроде «Состав»\n * или «Поведение»), один короткий пример и оглавление остального с размерами.\n * Справочные секции, остальные примеры и весь AI.md запрашиваются параметрами;\n * длинный кусок отдаётся порциями по `MAX_CHUNK` символов с подсказкой, как\n * получить продолжение.\n */\nimport type { ParsedComponent } from \"../types/index.js\";\n\n/** Параметры tool `get_component` помимо имени. `section`, `example`, `full` — взаимоисключающие. */\nexport interface ComponentQuery {\n section?: string;\n example?: string;\n full?: boolean;\n offset?: number;\n}\n\nexport type ComponentResult = { ok: true; text: string } | { ok: false; text: string };\n\n/** Максимум символов в одной порции ответа — с запасом под порог клиентов в ~25 тыс. */\nexport const MAX_CHUNK = 20_000;\n\n/**\n * Пример попадает в компактный ответ, только если он не длиннее. Порог с\n * расчётом на `Default` составного компонента: у `LightBox` он 6,2 тыс. и\n * показывает, как собираются `Content`, `Page` и `Controls`.\n */\nexport const SHORT_EXAMPLE_MAX = 6_500;\n\nexport const EXAMPLES_SECTION = \"Примеры использования\";\n\n/**\n * Справочные секции AI.md: в компактном ответе они только в оглавлении.\n * Список закрытый намеренно — секция с новым заголовком по умолчанию считается\n * частью API и попадает в ответ: лишние символы дешевле потерянного props.\n */\nexport const REFERENCE_SECTIONS: ReadonlySet<string> = new Set([\n \"Дизайн-токены\",\n \"Связанные компоненты\",\n \"Stories\",\n \"История изменений\",\n \"Файловая структура\",\n \"Ключевые особенности реализации\",\n EXAMPLES_SECTION,\n]);\n\nconst SUBSECTION_HEADING_RE = /^###\\s+(.+?)\\s*$/;\nconst FENCE_RE = /^\\s*```/;\nconst TRAILING_RULE_RE = /\\n+-{3,}\\s*$/;\n\n/** Порция длинного текста: `next` — смещение продолжения, null — текст закончился. */\nexport interface Chunk {\n body: string;\n next: number | null;\n}\n\n/**\n * Режет текст на порции не длиннее `MAX_CHUNK`, стараясь закончить порцию на\n * переводе строки — чтобы не рвать строку кода или таблицы посередине.\n */\nexport function paginate(text: string, offset: number): Chunk {\n if (text.length - offset <= MAX_CHUNK) {\n return { body: text.slice(offset), next: null };\n }\n\n const hardEnd = offset + MAX_CHUNK;\n const newline = text.lastIndexOf(\"\\n\", hardEnd - 1);\n const end = newline > offset + MAX_CHUNK / 2 ? newline + 1 : hardEnd;\n return { body: text.slice(offset, end), next: end };\n}\n\n/**\n * Подсекции `### {Заголовок}` — в «Примерах использования» это отдельные\n * примеры. Заголовки внутри блоков кода не считаются.\n */\nexport function extractSubsections(text: string): Record<string, string> {\n const result: Record<string, string> = {};\n let current: string | null = null;\n let buffer: string[] = [];\n let inFence = false;\n\n const flush = () => {\n if (current !== null) {\n result[current] = buffer.join(\"\\n\").trim();\n }\n };\n\n for (const line of text.split(\"\\n\")) {\n if (FENCE_RE.test(line)) {\n inFence = !inFence;\n }\n const match = inFence ? null : SUBSECTION_HEADING_RE.exec(line);\n if (match) {\n flush();\n current = match[1];\n buffer = [];\n } else if (current !== null) {\n buffer.push(line);\n }\n }\n flush();\n return result;\n}\n\n/** Текст секции без завершающего разделителя `---`: в AI.md им закрыта каждая секция. */\nfunction sectionText(text: string): string {\n return text.replace(TRAILING_RULE_RE, \"\").trim();\n}\n\nfunction findKey(record: Record<string, string>, wanted: string): string | undefined {\n const needle = wanted.trim().toLowerCase();\n return Object.keys(record).find((key) => key.toLowerCase() === needle);\n}\n\nfunction quoteList(names: string[]): string {\n return names.map((name) => JSON.stringify(name)).join(\", \");\n}\n\nfunction callHint(name: string, args: Record<string, unknown>): string {\n return `get_component ${JSON.stringify({ name, ...args })}`;\n}\n\n/** Строка метаданных из frontmatter: категория, связанные компоненты, Figma, токены. */\nfunction metaLine(component: ParsedComponent): string | null {\n const parts: string[] = [];\n if (component.category) {\n parts.push(`Категория: ${component.category}`);\n }\n if (component.related.length > 0) {\n parts.push(`Связанные: ${component.related.join(\", \")}`);\n }\n if (component.figma.file || component.figma.node) {\n parts.push(`Figma: ${[component.figma.file, component.figma.node].filter(Boolean).join(\", \")}`);\n }\n if (component.tokens.length > 0) {\n parts.push(\n `Токены (${component.tokens.length}): get_tokens ${JSON.stringify({ component: component.name })}`,\n );\n }\n return parts.length > 0 ? parts.join(\" · \") : null;\n}\n\n/** Короткий пример для компактного ответа: `Default`, иначе самый короткий из подходящих. */\nfunction pickShortExample(examples: Record<string, string>): string | null {\n const fitting = Object.keys(examples).filter((key) => examples[key].length <= SHORT_EXAMPLE_MAX);\n if (fitting.length === 0) {\n return null;\n }\n const byDefault = fitting.find((key) => key.toLowerCase() === \"default\");\n if (byDefault) {\n return byDefault;\n }\n return fitting.reduce((best, key) => (examples[key].length < examples[best].length ? key : best));\n}\n\nfunction buildCompact(component: ParsedComponent): string {\n const { sections } = component;\n const parts: string[] = [`# ${component.name}`];\n\n const meta = metaLine(component);\n if (meta) {\n parts.push(meta);\n }\n\n for (const [title, text] of Object.entries(sections)) {\n if (!REFERENCE_SECTIONS.has(title)) {\n parts.push(`## ${title}\\n\\n${sectionText(text)}`);\n }\n }\n\n const examples = extractSubsections(sections[EXAMPLES_SECTION] ?? \"\");\n const shown = pickShortExample(examples);\n if (shown) {\n parts.push(`## Пример: ${shown}\\n\\n${examples[shown]}`);\n }\n\n const moreSections = Object.keys(sections)\n .filter((title) => REFERENCE_SECTIONS.has(title) && title !== EXAMPLES_SECTION)\n .map((title) => `${JSON.stringify(title)} ${sectionText(sections[title]).length}`);\n const moreExamples = Object.keys(examples)\n .filter((title) => title !== shown)\n .map((title) => `${JSON.stringify(title)} ${examples[title].length}`);\n\n const more = [\n \"## Ещё\\n\",\n \"Это компактный ответ. Остальное — тем же get_component, одним из параметров (размер в символах):\",\n ];\n if (moreSections.length > 0) {\n more.push(`- section: ${moreSections.join(\", \")}`);\n }\n if (moreExamples.length > 0) {\n more.push(`- example: ${moreExamples.join(\", \")}`);\n }\n more.push(`- full: true — весь AI.md, ${(component.markdown ?? \"\").length}`);\n parts.push(more.join(\"\\n\"));\n\n return parts.join(\"\\n\\n\");\n}\n\nfunction buildFallback(component: ParsedComponent): string {\n const stories = component.stories ? ` Stories: \\`${component.stories}\\`.` : \"\";\n return `# ${component.name}\\n\\nAI-документации у компонента нет (ai_ready: false).${stories}`;\n}\n\n/** Выбранный параметрами кусок AI.md или текст ошибки. */\nfunction selectPiece(\n component: ParsedComponent,\n query: ComponentQuery,\n): { ok: true; text: string; args: Record<string, unknown> } | { ok: false; text: string } {\n const { sections } = component;\n\n if (query.section !== undefined) {\n const key = findKey(sections, query.section);\n if (key === undefined) {\n return {\n ok: false,\n text: `Секции ${JSON.stringify(query.section)} у ${component.name} нет. Есть: ${quoteList(Object.keys(sections))}.`,\n };\n }\n return { ok: true, text: `## ${key}\\n\\n${sectionText(sections[key])}`, args: { section: key } };\n }\n\n if (query.example !== undefined) {\n const examples = extractSubsections(sections[EXAMPLES_SECTION] ?? \"\");\n const key = findKey(examples, query.example);\n if (key === undefined) {\n const names = Object.keys(examples);\n return {\n ok: false,\n text:\n names.length > 0\n ? `Примера ${JSON.stringify(query.example)} у ${component.name} нет. Есть: ${quoteList(names)}.`\n : `У ${component.name} нет секции «${EXAMPLES_SECTION}».`,\n };\n }\n return { ok: true, text: `### ${key}\\n\\n${examples[key]}`, args: { example: key } };\n }\n\n if (query.full) {\n const meta = metaLine(component);\n const body = component.markdown ?? \"\";\n return { ok: true, text: meta ? `${meta}\\n\\n${body}` : body, args: { full: true } };\n }\n\n return { ok: true, text: buildCompact(component), args: {} };\n}\n\nexport function buildComponentResponse(\n component: ParsedComponent,\n query: ComponentQuery = {},\n): ComponentResult {\n const selectors = [query.section !== undefined, query.example !== undefined, query.full === true];\n if (selectors.filter(Boolean).length > 1) {\n return { ok: false, text: \"Укажи не больше одного из параметров: section, example, full.\" };\n }\n\n if (!component.ai_ready) {\n return { ok: true, text: buildFallback(component) };\n }\n\n const piece = selectPiece(component, query);\n if (!piece.ok) {\n return piece;\n }\n\n const offset = query.offset ?? 0;\n if (offset > 0 && offset >= piece.text.length) {\n return {\n ok: false,\n text: `offset ${offset} за концом ответа: в нём ${piece.text.length} символов.`,\n };\n }\n\n const chunk = paginate(piece.text, offset);\n const end = offset + chunk.body.length;\n const lines: string[] = [];\n if (offset > 0) {\n lines.push(`— Продолжение: символы ${offset}–${end} из ${piece.text.length} —\\n`);\n }\n lines.push(chunk.body);\n if (chunk.next !== null) {\n lines.push(\n `\\n— Показаны символы ${offset}–${end} из ${piece.text.length}. ` +\n `Продолжение: ${callHint(component.name, { ...piece.args, offset: chunk.next })} —`,\n );\n }\n return { ok: true, text: lines.join(\"\\n\") };\n}\n","/**\n * Сборка ответа tool `get_guidelines`.\n *\n * Гайдлайны кодогенерации (`docs/mcp/guidelines.md` в triplex-next, правила\n * `TPX-G-NN`) приезжают через bundle как guide с топиком `guidelines` —\n * начиная с triplex-next 1.45.0. На более старом bundle топика нет: сервер\n * обязан работать и в этом случае, отвечая внятной ошибкой, а не падая.\n */\nimport type { ParsedBundle } from \"../types/index.js\";\n\nexport const GUIDELINES_TOPIC = \"guidelines\";\n\nexport type GuidelinesResult = { ok: true; text: string } | { ok: false; text: string };\n\nexport function buildGuidelinesResponse(bundle: ParsedBundle): GuidelinesResult {\n const guide = bundle.guides.find((g) => g.topic === GUIDELINES_TOPIC);\n\n if (!guide) {\n return {\n ok: false,\n text:\n `Bundle собран из triplex-next ${bundle.triplexVersion} и гайдлайнов не содержит — ` +\n \"они поставляются начиная с 1.45.0. Обновите bundle: npm run fetch-bundle.\",\n };\n }\n\n return { ok: true, text: guide.raw };\n}\n","/**\n * Сборка ответа tool `get_tokens`.\n *\n * Токены Triplex адресуются путём `Группа.Токен` — ровно в этом виде они\n * передаются в `ThemeProvider` через prop `tokens`. CSS-переменные\n * `--triplex-next-*` публичным API не являются: на сборке библиотеки к имени\n * дописывается версия пакета.\n *\n * Дерево токенов приходит в bundle начиная с `schemaVersion: 2`. Для более\n * старых bundle доступны только пути из frontmatter AI.md — ответ в этом случае\n * помечается `note`, а сервер продолжает работать.\n */\nimport type { ParsedBundle, TokenEntry, TokensSection } from \"../types/index.js\";\n\n/** Фильтры tool `get_tokens`. Оба необязательны, `group` имеет приоритет. */\nexport interface TokensQuery {\n component?: string;\n group?: string;\n}\n\nexport type TokensResult = { ok: true; payload: unknown } | { ok: false; text: string };\n\nexport const LEGACY_NOTE =\n \"Bundle собран до schemaVersion 2 и значений токенов не содержит — доступны только пути. Обновите bundle: npm run fetch-bundle.\";\n\n/** Как потребитель переопределяет токен: единственный публичный способ. */\nfunction howToOverride(group: string) {\n return {\n api: \"<ThemeProvider tokens={...}> из @sberbusiness/triplex-next\",\n example: [\n \"const TOKENS = {\",\n ` ${group}: {`,\n ' <Токен>: {value: \"#FFFFFF\"}, // своё значение',\n ' <Другой>: {ref: \"ColorBrand.50\"}, // ссылка на core-токен',\n \" },\",\n \"};\",\n \"\",\n \"<ThemeProvider tokens={TOKENS} scopeRef={scopeRef}>…</ThemeProvider>\",\n ].join(\"\\n\"),\n notes: [\n \"Объект tokens плоский: группы лежат на верхнем уровне, вложенности core/components нет.\",\n \"Одним объектом можно переопределить несколько групп сразу — и core, и компонентные.\",\n \"ref указывает только на core-токены (refable: true).\",\n \"tokens сравнивается по ссылке — выносите объект из рендера.\",\n \"Переопределение действует внутри элемента из scopeRef.\",\n ],\n };\n}\n\n/** Внутренний слой: css-переменные с версией пакета в имени. */\nfunction internalNote(section: TokensSection) {\n return {\n cssVarPattern: section.internal.cssVarPattern,\n note: \"Внутренняя реализация: в собранном пакете к имени переменной добавляется версия, поэтому в коде потребителя использовать её нельзя.\",\n };\n}\n\n/** Core-токены, на которые ссылаются переданные токены. */\nfunction coreTokensUsed(tokens: TokenEntry[]): string[] {\n const refs = tokens.flatMap((token) =>\n [token.light.ref, token.dark.ref].filter((ref): ref is string => ref !== undefined),\n );\n\n return [...new Set(refs)].sort();\n}\n\n/** Индекс групп: имя → число токенов. Полное дерево слишком велико для одного ответа. */\nfunction groupIndex(section: TokensSection, kind: \"core\" | \"component\"): Record<string, number> {\n return Object.fromEntries(\n Object.entries(section.groups)\n .filter(([, group]) => group.kind === kind)\n .map(([name, group]) => [name, Object.keys(group.tokens).length]),\n );\n}\n\nfunction byGroup(section: TokensSection, group: string): TokensResult {\n const name = Object.keys(section.groups).find((key) => key.toLowerCase() === group.toLowerCase());\n\n if (name === undefined) {\n return {\n ok: false,\n text: `Группа токенов \"${group}\" не найдена. Список групп: get_tokens() без аргументов.`,\n };\n }\n\n const entry = section.groups[name];\n\n return {\n ok: true,\n payload: {\n group: name,\n kind: entry.kind,\n refable: entry.refable,\n tokenCount: Object.keys(entry.tokens).length,\n howToOverride: howToOverride(name),\n tokens: Object.values(entry.tokens),\n internal: internalNote(section),\n },\n };\n}\n\nfunction byComponent(\n bundle: ParsedBundle,\n section: TokensSection | null,\n component: string,\n): TokensResult {\n const found = bundle.components.find((c) => c.name.toLowerCase() === component.toLowerCase());\n\n if (!found) {\n return {\n ok: false,\n text: `Компонент \"${component}\" не найден. Используйте list_components для списка доступных компонентов.`,\n };\n }\n\n if (section === null) {\n return {\n ok: true,\n payload: { component: found.name, tokens: found.tokens, note: LEGACY_NOTE },\n };\n }\n\n // Компонент может использовать токены нескольких групп: например, поле выбора\n // красится токенами FormField, Dropdown и DropdownList сразу.\n const resolved = found.tokens.map((path) => {\n const [group, token] = path.split(\".\");\n\n return { path, entry: section.groups[group]?.tokens[token] };\n });\n const known = resolved\n .map(({ entry }) => entry)\n .filter((entry): entry is TokenEntry => entry !== undefined);\n const unknown = resolved.filter(({ entry }) => entry === undefined).map(({ path }) => path);\n const groups = [...new Set(known.map((token) => token.path.split(\".\")[0]))];\n\n return {\n ok: true,\n payload: {\n component: found.name,\n groups,\n tokenCount: known.length,\n howToOverride: howToOverride(groups[0] ?? \"Группа\"),\n tokens: known,\n // Палитра, на которую ссылаются токены компонента: перекрасив core-токен,\n // потребитель меняет вид всех компонентов, которые на него ссылаются.\n coreTokensUsed: coreTokensUsed(known),\n ...(unknown.length ? { unknownTokens: unknown } : {}),\n internal: internalNote(section),\n },\n };\n}\n\n/** Собирает ответ `get_tokens` по фильтрам. Без фильтров возвращает индекс групп. */\nexport function buildTokensResponse(bundle: ParsedBundle, query: TokensQuery): TokensResult {\n const section = bundle.tokens;\n\n if (query.group !== undefined) {\n return section === null ? { ok: false, text: LEGACY_NOTE } : byGroup(section, query.group);\n }\n\n if (query.component !== undefined) {\n return byComponent(bundle, section, query.component);\n }\n\n if (section === null) {\n return {\n ok: true,\n payload: {\n note: LEGACY_NOTE,\n components: bundle.components\n .filter((c) => c.tokens.length > 0)\n .map((c) => ({ component: c.name, tokens: c.tokens })),\n },\n };\n }\n\n return {\n ok: true,\n payload: {\n triplexVersion: bundle.triplexVersion,\n overridePath: section.overridePath,\n core: {\n description: 'Палитра и примитивы. Ссылки { ref: \"ColorBrand.50\" } резолвятся сюда.',\n groups: groupIndex(section, \"core\"),\n },\n components: { groups: groupIndex(section, \"component\") },\n hint: 'Полные данные: get_tokens({ component: \"Calendar\" }) или get_tokens({ group: \"ColorBrand\" }).',\n },\n };\n}\n"],"mappings":";;;AAAA,SAAS,4BAA4B;AACrC,SAAS,wBAAwB;;;ACDjC,SAAS,iBAAiB;;;ACC1B,SAAS,SAAS;;;ACDlB,SAAS,YAAY,oBAAoB;AACzC,SAAS,SAAS,eAAe;AACjC,SAAS,qBAAqB;;;ACF9B,OAAO,YAAY;AAGnB,IAAM,qBAAqB;AAEpB,SAAS,eAAe,KAAoC;AACjE,MAAI,IAAI,QAAQ,MAAM;AACpB,UAAM,WAAW,IAAI,YAAY,EAAE,MAAM,IAAI,MAAM,aAAa,KAAK;AACrE,WAAO;AAAA,MACL,MAAM,IAAI;AAAA,MACV,MAAM,IAAI;AAAA,MACV,UAAU;AAAA,MACV,UAAU;AAAA,MACV,aAAa;AAAA,MACb,OAAO,EAAE,MAAM,MAAM,MAAM,KAAK;AAAA,MAChC,SAAS,CAAC;AAAA,MACV,QAAQ,CAAC;AAAA,MACT,SAAS,SAAS;AAAA,MAClB,UAAU,CAAC;AAAA,MACX,UAAU;AAAA,IACZ;AAAA,EACF;AAEA,QAAM,SAAS,OAAO,IAAI,GAAG;AAC7B,QAAM,KAAK,OAAO;AAClB,QAAM,OAAO,OAAO;AACpB,QAAM,WAAW,gBAAgB,IAAI;AAErC,SAAO;AAAA,IACL,MAAM,IAAI;AAAA,IACV,MAAM,IAAI;AAAA,IACV,UAAU;AAAA,IACV,UAAU,GAAG,YAAY;AAAA,IACzB,aAAa,mBAAmB,QAAQ;AAAA,IACxC,OAAO;AAAA,MACL,MAAM,SAAS,GAAG,YAAY,CAAC;AAAA,MAC/B,MAAM,SAAS,GAAG,YAAY,CAAC;AAAA,IACjC;AAAA,IACA,SAAS,MAAM,QAAQ,GAAG,OAAO,IAAI,GAAG,UAAU,CAAC;AAAA,IACnD,QAAQ,MAAM,QAAQ,GAAG,MAAM,IAAI,GAAG,SAAS,CAAC;AAAA,IAChD,SAAS,GAAG,WAAW;AAAA,IACvB;AAAA,IACA,UAAU;AAAA,EACZ;AACF;AAEA,SAAS,gBAAgB,MAAsC;AAC7D,QAAM,WAAmC,CAAC;AAC1C,MAAI,eAA8B;AAClC,MAAI,SAAmB,CAAC;AAExB,QAAM,QAAQ,MAAM;AAClB,QAAI,iBAAiB,MAAM;AACzB,eAAS,YAAY,IAAI,OAAO,KAAK,IAAI,EAAE,KAAK;AAAA,IAClD;AAAA,EACF;AAEA,aAAW,QAAQ,KAAK,MAAM,IAAI,GAAG;AACnC,UAAM,QAAQ,mBAAmB,KAAK,IAAI;AAC1C,QAAI,OAAO;AACT,YAAM;AACN,qBAAe,MAAM,CAAC;AACtB,eAAS,CAAC;AAAA,IACZ,WAAW,iBAAiB,MAAM;AAChC,aAAO,KAAK,IAAI;AAAA,IAClB;AAAA,EACF;AACA,QAAM;AACN,SAAO;AACT;AAEA,SAAS,mBAAmB,UAAiD;AAC3E,QAAM,UAAU,SAAS,8DAAY;AACrC,MAAI,CAAC,SAAS;AACZ,WAAO;AAAA,EACT;AACA,QAAM,iBAAiB,QACpB,MAAM,SAAS,EACf,IAAI,CAAC,MAAM,EAAE,KAAK,CAAC,EACnB,KAAK,CAAC,MAAM,EAAE,SAAS,CAAC;AAC3B,SAAO,kBAAkB;AAC3B;AAEA,SAAS,SAAS,OAA0C;AAC1D,MAAI,OAAO,UAAU,UAAU;AAC7B,WAAO;AAAA,EACT;AACA,QAAM,UAAU,MAAM,KAAK;AAC3B,SAAO,QAAQ,SAAS,IAAI,UAAU;AACxC;;;AD7EA,IAAM,eAA6B;AAAA,EACjC,eAAe;AAAA,EACf,gBAAgB;AAAA,EAChB,cAAa,oBAAI,KAAK,CAAC,GAAE,YAAY;AAAA,EACrC,YAAY,CAAC;AAAA,EACb,QAAQ,CAAC;AAAA,EACT,cAAc,CAAC;AAAA,EACf,QAAQ;AACV;AAEA,IAAM,cAA2B;AAAA,EAC/B,eAAe;AAAA,EACf,aAAa;AAAA,EACb,gBAAgB;AAAA,EAChB,cAAa,oBAAI,KAAK,CAAC,GAAE,YAAY;AAAA,EACrC,OAAO,CAAC;AACV;AAQA,SAAS,gBAAgB,UAA0B;AACjD,MAAI,MAAM;AACV,SAAO,QAAQ,QAAQ,GAAG,GAAG;AAC3B,QAAI,WAAW,QAAQ,KAAK,cAAc,CAAC,GAAG;AAC5C,aAAO;AAAA,IACT;AACA,UAAM,QAAQ,GAAG;AAAA,EACnB;AACA,QAAM,IAAI,MAAM,gCAAgC,QAAQ,EAAE;AAC5D;AAEA,IAAM,eAAe,gBAAgB,QAAQ,cAAc,YAAY,GAAG,CAAC,CAAC;AAC5E,IAAM,aAAa,QAAQ,cAAc,QAAQ;AACjD,IAAM,gBAAgB,QAAQ,YAAY,eAAe;AACzD,IAAM,aAAa,QAAQ,YAAY,YAAY;AAE5C,SAAS,YAAyB;AACvC,MAAI;AACF,WAAO,KAAK,MAAM,aAAa,YAAY,OAAO,CAAC;AAAA,EACrD,QAAQ;AACN,YAAQ,MAAM,6BAA6B,UAAU,oCAAoC;AACzF,WAAO;AAAA,EACT;AACF;AAMA,SAAS,WAAW,UAA0C;AAC5D,MAAI,CAAC,SAAS,QAAQ;AACpB,WAAO;AAAA,EACT;AAEA,MAAI;AACF,WAAO,KAAK,MAAM,aAAa,QAAQ,YAAY,SAAS,MAAM,GAAG,OAAO,CAAC;AAAA,EAC/E,QAAQ;AACN,YAAQ;AAAA,MACN,8BAA8B,SAAS,MAAM;AAAA,IAC/C;AACA,WAAO;AAAA,EACT;AACF;AAEO,SAAS,aAA2B;AACzC,MAAI;AACJ,MAAI;AACF,eAAW,KAAK,MAAM,aAAa,eAAe,OAAO,CAAC;AAAA,EAC5D,QAAQ;AACN,YAAQ;AAAA,MACN,gCAAgC,aAAa;AAAA,IAC/C;AACA,WAAO;AAAA,EACT;AAEA,SAAO;AAAA,IACL,eAAe,SAAS;AAAA,IACxB,gBAAgB,SAAS;AAAA,IACzB,aAAa,SAAS;AAAA,IACtB,YAAY,SAAS,WAAW,IAAI,CAAC,OAAO;AAC1C,YAAM,MACJ,GAAG,SAAS,OACR;AAAA,QACE,MAAM,GAAG;AAAA,QACT,MAAM,GAAG;AAAA,QACT,KAAK,aAAa,QAAQ,YAAY,GAAG,IAAI,GAAG,OAAO;AAAA,QACvD,UAAU,CAAC;AAAA,QACX,UAAU;AAAA,MACZ,IACA;AAAA,QACE,MAAM,GAAG;AAAA,QACT,MAAM,GAAG;AAAA,QACT,KAAK;AAAA,QACL,UAAU,CAAC;AAAA,QACX,UAAU;AAAA,UACR,MAAM,GAAG;AAAA,UACT,aAAa,GAAG,eAAe;AAAA,QACjC;AAAA,MACF;AACN,aAAO,eAAe,GAAG;AAAA,IAC3B,CAAC;AAAA,IACD,QAAQ,SAAS,OAAO,IAAI,CAAC,OAAO;AAAA,MAClC,OAAO,EAAE;AAAA,MACT,MAAM,EAAE;AAAA,MACR,KAAK,aAAa,QAAQ,YAAY,EAAE,IAAI,GAAG,OAAO;AAAA,IACxD,EAAE;AAAA,IACF,cAAc,SAAS,aAAa,IAAI,CAAC,OAAO;AAAA,MAC9C,SAAS,EAAE;AAAA,MACX,MAAM,EAAE;AAAA,MACR,KAAK,aAAa,QAAQ,YAAY,EAAE,IAAI,GAAG,OAAO;AAAA,IACxD,EAAE;AAAA,IACF,QAAQ,WAAW,QAAQ;AAAA,EAC7B;AACF;;;AErGO,IAAM,YAAY;AAOlB,IAAM,oBAAoB;AAE1B,IAAM,mBAAmB;AAOzB,IAAM,qBAA0C,oBAAI,IAAI;AAAA,EAC7D;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF,CAAC;AAED,IAAM,wBAAwB;AAC9B,IAAM,WAAW;AACjB,IAAM,mBAAmB;AAYlB,SAAS,SAAS,MAAc,QAAuB;AAC5D,MAAI,KAAK,SAAS,UAAU,WAAW;AACrC,WAAO,EAAE,MAAM,KAAK,MAAM,MAAM,GAAG,MAAM,KAAK;AAAA,EAChD;AAEA,QAAM,UAAU,SAAS;AACzB,QAAM,UAAU,KAAK,YAAY,MAAM,UAAU,CAAC;AAClD,QAAM,MAAM,UAAU,SAAS,YAAY,IAAI,UAAU,IAAI;AAC7D,SAAO,EAAE,MAAM,KAAK,MAAM,QAAQ,GAAG,GAAG,MAAM,IAAI;AACpD;AAMO,SAAS,mBAAmB,MAAsC;AACvE,QAAM,SAAiC,CAAC;AACxC,MAAI,UAAyB;AAC7B,MAAI,SAAmB,CAAC;AACxB,MAAI,UAAU;AAEd,QAAM,QAAQ,MAAM;AAClB,QAAI,YAAY,MAAM;AACpB,aAAO,OAAO,IAAI,OAAO,KAAK,IAAI,EAAE,KAAK;AAAA,IAC3C;AAAA,EACF;AAEA,aAAW,QAAQ,KAAK,MAAM,IAAI,GAAG;AACnC,QAAI,SAAS,KAAK,IAAI,GAAG;AACvB,gBAAU,CAAC;AAAA,IACb;AACA,UAAM,QAAQ,UAAU,OAAO,sBAAsB,KAAK,IAAI;AAC9D,QAAI,OAAO;AACT,YAAM;AACN,gBAAU,MAAM,CAAC;AACjB,eAAS,CAAC;AAAA,IACZ,WAAW,YAAY,MAAM;AAC3B,aAAO,KAAK,IAAI;AAAA,IAClB;AAAA,EACF;AACA,QAAM;AACN,SAAO;AACT;AAGA,SAAS,YAAY,MAAsB;AACzC,SAAO,KAAK,QAAQ,kBAAkB,EAAE,EAAE,KAAK;AACjD;AAEA,SAAS,QAAQ,QAAgC,QAAoC;AACnF,QAAM,SAAS,OAAO,KAAK,EAAE,YAAY;AACzC,SAAO,OAAO,KAAK,MAAM,EAAE,KAAK,CAAC,QAAQ,IAAI,YAAY,MAAM,MAAM;AACvE;AAEA,SAAS,UAAU,OAAyB;AAC1C,SAAO,MAAM,IAAI,CAAC,SAAS,KAAK,UAAU,IAAI,CAAC,EAAE,KAAK,IAAI;AAC5D;AAEA,SAAS,SAAS,MAAc,MAAuC;AACrE,SAAO,iBAAiB,KAAK,UAAU,EAAE,MAAM,GAAG,KAAK,CAAC,CAAC;AAC3D;AAGA,SAAS,SAAS,WAA2C;AAC3D,QAAM,QAAkB,CAAC;AACzB,MAAI,UAAU,UAAU;AACtB,UAAM,KAAK,2DAAc,UAAU,QAAQ,EAAE;AAAA,EAC/C;AACA,MAAI,UAAU,QAAQ,SAAS,GAAG;AAChC,UAAM,KAAK,2DAAc,UAAU,QAAQ,KAAK,IAAI,CAAC,EAAE;AAAA,EACzD;AACA,MAAI,UAAU,MAAM,QAAQ,UAAU,MAAM,MAAM;AAChD,UAAM,KAAK,UAAU,CAAC,UAAU,MAAM,MAAM,UAAU,MAAM,IAAI,EAAE,OAAO,OAAO,EAAE,KAAK,IAAI,CAAC,EAAE;AAAA,EAChG;AACA,MAAI,UAAU,OAAO,SAAS,GAAG;AAC/B,UAAM;AAAA,MACJ,yCAAW,UAAU,OAAO,MAAM,iBAAiB,KAAK,UAAU,EAAE,WAAW,UAAU,KAAK,CAAC,CAAC;AAAA,IAClG;AAAA,EACF;AACA,SAAO,MAAM,SAAS,IAAI,MAAM,KAAK,QAAK,IAAI;AAChD;AAGA,SAAS,iBAAiB,UAAiD;AACzE,QAAM,UAAU,OAAO,KAAK,QAAQ,EAAE,OAAO,CAAC,QAAQ,SAAS,GAAG,EAAE,UAAU,iBAAiB;AAC/F,MAAI,QAAQ,WAAW,GAAG;AACxB,WAAO;AAAA,EACT;AACA,QAAM,YAAY,QAAQ,KAAK,CAAC,QAAQ,IAAI,YAAY,MAAM,SAAS;AACvE,MAAI,WAAW;AACb,WAAO;AAAA,EACT;AACA,SAAO,QAAQ,OAAO,CAAC,MAAM,QAAS,SAAS,GAAG,EAAE,SAAS,SAAS,IAAI,EAAE,SAAS,MAAM,IAAK;AAClG;AAEA,SAAS,aAAa,WAAoC;AACxD,QAAM,EAAE,SAAS,IAAI;AACrB,QAAM,QAAkB,CAAC,KAAK,UAAU,IAAI,EAAE;AAE9C,QAAM,OAAO,SAAS,SAAS;AAC/B,MAAI,MAAM;AACR,UAAM,KAAK,IAAI;AAAA,EACjB;AAEA,aAAW,CAAC,OAAO,IAAI,KAAK,OAAO,QAAQ,QAAQ,GAAG;AACpD,QAAI,CAAC,mBAAmB,IAAI,KAAK,GAAG;AAClC,YAAM,KAAK,MAAM,KAAK;AAAA;AAAA,EAAO,YAAY,IAAI,CAAC,EAAE;AAAA,IAClD;AAAA,EACF;AAEA,QAAM,WAAW,mBAAmB,SAAS,gBAAgB,KAAK,EAAE;AACpE,QAAM,QAAQ,iBAAiB,QAAQ;AACvC,MAAI,OAAO;AACT,UAAM,KAAK,4CAAc,KAAK;AAAA;AAAA,EAAO,SAAS,KAAK,CAAC,EAAE;AAAA,EACxD;AAEA,QAAM,eAAe,OAAO,KAAK,QAAQ,EACtC,OAAO,CAAC,UAAU,mBAAmB,IAAI,KAAK,KAAK,UAAU,gBAAgB,EAC7E,IAAI,CAAC,UAAU,GAAG,KAAK,UAAU,KAAK,CAAC,IAAI,YAAY,SAAS,KAAK,CAAC,EAAE,MAAM,EAAE;AACnF,QAAM,eAAe,OAAO,KAAK,QAAQ,EACtC,OAAO,CAAC,UAAU,UAAU,KAAK,EACjC,IAAI,CAAC,UAAU,GAAG,KAAK,UAAU,KAAK,CAAC,IAAI,SAAS,KAAK,EAAE,MAAM,EAAE;AAEtE,QAAM,OAAO;AAAA,IACX;AAAA,IACA;AAAA,EACF;AACA,MAAI,aAAa,SAAS,GAAG;AAC3B,SAAK,KAAK,cAAc,aAAa,KAAK,IAAI,CAAC,EAAE;AAAA,EACnD;AACA,MAAI,aAAa,SAAS,GAAG;AAC3B,SAAK,KAAK,cAAc,aAAa,KAAK,IAAI,CAAC,EAAE;AAAA,EACnD;AACA,OAAK,KAAK,wDAA+B,UAAU,YAAY,IAAI,MAAM,EAAE;AAC3E,QAAM,KAAK,KAAK,KAAK,IAAI,CAAC;AAE1B,SAAO,MAAM,KAAK,MAAM;AAC1B;AAEA,SAAS,cAAc,WAAoC;AACzD,QAAM,UAAU,UAAU,UAAU,eAAe,UAAU,OAAO,QAAQ;AAC5E,SAAO,KAAK,UAAU,IAAI;AAAA;AAAA,uLAA0D,OAAO;AAC7F;AAGA,SAAS,YACP,WACA,OACyF;AACzF,QAAM,EAAE,SAAS,IAAI;AAErB,MAAI,MAAM,YAAY,QAAW;AAC/B,UAAM,MAAM,QAAQ,UAAU,MAAM,OAAO;AAC3C,QAAI,QAAQ,QAAW;AACrB,aAAO;AAAA,QACL,IAAI;AAAA,QACJ,MAAM,wCAAU,KAAK,UAAU,MAAM,OAAO,CAAC,WAAM,UAAU,IAAI,kDAAe,UAAU,OAAO,KAAK,QAAQ,CAAC,CAAC;AAAA,MAClH;AAAA,IACF;AACA,WAAO,EAAE,IAAI,MAAM,MAAM,MAAM,GAAG;AAAA;AAAA,EAAO,YAAY,SAAS,GAAG,CAAC,CAAC,IAAI,MAAM,EAAE,SAAS,IAAI,EAAE;AAAA,EAChG;AAEA,MAAI,MAAM,YAAY,QAAW;AAC/B,UAAM,WAAW,mBAAmB,SAAS,gBAAgB,KAAK,EAAE;AACpE,UAAM,MAAM,QAAQ,UAAU,MAAM,OAAO;AAC3C,QAAI,QAAQ,QAAW;AACrB,YAAM,QAAQ,OAAO,KAAK,QAAQ;AAClC,aAAO;AAAA,QACL,IAAI;AAAA,QACJ,MACE,MAAM,SAAS,IACX,8CAAW,KAAK,UAAU,MAAM,OAAO,CAAC,WAAM,UAAU,IAAI,kDAAe,UAAU,KAAK,CAAC,MAC3F,UAAK,UAAU,IAAI,gEAAgB,gBAAgB;AAAA,MAC3D;AAAA,IACF;AACA,WAAO,EAAE,IAAI,MAAM,MAAM,OAAO,GAAG;AAAA;AAAA,EAAO,SAAS,GAAG,CAAC,IAAI,MAAM,EAAE,SAAS,IAAI,EAAE;AAAA,EACpF;AAEA,MAAI,MAAM,MAAM;AACd,UAAM,OAAO,SAAS,SAAS;AAC/B,UAAM,OAAO,UAAU,YAAY;AACnC,WAAO,EAAE,IAAI,MAAM,MAAM,OAAO,GAAG,IAAI;AAAA;AAAA,EAAO,IAAI,KAAK,MAAM,MAAM,EAAE,MAAM,KAAK,EAAE;AAAA,EACpF;AAEA,SAAO,EAAE,IAAI,MAAM,MAAM,aAAa,SAAS,GAAG,MAAM,CAAC,EAAE;AAC7D;AAEO,SAAS,uBACd,WACA,QAAwB,CAAC,GACR;AACjB,QAAM,YAAY,CAAC,MAAM,YAAY,QAAW,MAAM,YAAY,QAAW,MAAM,SAAS,IAAI;AAChG,MAAI,UAAU,OAAO,OAAO,EAAE,SAAS,GAAG;AACxC,WAAO,EAAE,IAAI,OAAO,MAAM,2NAAgE;AAAA,EAC5F;AAEA,MAAI,CAAC,UAAU,UAAU;AACvB,WAAO,EAAE,IAAI,MAAM,MAAM,cAAc,SAAS,EAAE;AAAA,EACpD;AAEA,QAAM,QAAQ,YAAY,WAAW,KAAK;AAC1C,MAAI,CAAC,MAAM,IAAI;AACb,WAAO;AAAA,EACT;AAEA,QAAM,SAAS,MAAM,UAAU;AAC/B,MAAI,SAAS,KAAK,UAAU,MAAM,KAAK,QAAQ;AAC7C,WAAO;AAAA,MACL,IAAI;AAAA,MACJ,MAAM,UAAU,MAAM,sHAA4B,MAAM,KAAK,MAAM;AAAA,IACrE;AAAA,EACF;AAEA,QAAM,QAAQ,SAAS,MAAM,MAAM,MAAM;AACzC,QAAM,MAAM,SAAS,MAAM,KAAK;AAChC,QAAM,QAAkB,CAAC;AACzB,MAAI,SAAS,GAAG;AACd,UAAM,KAAK,yHAA0B,MAAM,SAAI,GAAG,iBAAO,MAAM,KAAK,MAAM;AAAA,CAAM;AAAA,EAClF;AACA,QAAM,KAAK,MAAM,IAAI;AACrB,MAAI,MAAM,SAAS,MAAM;AACvB,UAAM;AAAA,MACJ;AAAA,qGAAwB,MAAM,SAAI,GAAG,iBAAO,MAAM,KAAK,MAAM,yEAC3C,SAAS,UAAU,MAAM,EAAE,GAAG,MAAM,MAAM,QAAQ,MAAM,KAAK,CAAC,CAAC;AAAA,IACnF;AAAA,EACF;AACA,SAAO,EAAE,IAAI,MAAM,MAAM,MAAM,KAAK,IAAI,EAAE;AAC5C;;;AC7RO,IAAM,mBAAmB;AAIzB,SAAS,wBAAwB,QAAwC;AAC9E,QAAM,QAAQ,OAAO,OAAO,KAAK,CAAC,MAAM,EAAE,UAAU,gBAAgB;AAEpE,MAAI,CAAC,OAAO;AACV,WAAO;AAAA,MACL,IAAI;AAAA,MACJ,MACE,yEAAiC,OAAO,cAAc;AAAA,IAE1D;AAAA,EACF;AAEA,SAAO,EAAE,IAAI,MAAM,MAAM,MAAM,IAAI;AACrC;;;ACLO,IAAM,cACX;AAGF,SAAS,cAAc,OAAe;AACpC,SAAO;AAAA,IACL,KAAK;AAAA,IACL,SAAS;AAAA,MACP;AAAA,MACA,KAAK,KAAK;AAAA,MACV;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,IACF,EAAE,KAAK,IAAI;AAAA,IACX,OAAO;AAAA,MACL;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,IACF;AAAA,EACF;AACF;AAGA,SAAS,aAAa,SAAwB;AAC5C,SAAO;AAAA,IACL,eAAe,QAAQ,SAAS;AAAA,IAChC,MAAM;AAAA,EACR;AACF;AAGA,SAAS,eAAe,QAAgC;AACtD,QAAM,OAAO,OAAO;AAAA,IAAQ,CAAC,UAC3B,CAAC,MAAM,MAAM,KAAK,MAAM,KAAK,GAAG,EAAE,OAAO,CAAC,QAAuB,QAAQ,MAAS;AAAA,EACpF;AAEA,SAAO,CAAC,GAAG,IAAI,IAAI,IAAI,CAAC,EAAE,KAAK;AACjC;AAGA,SAAS,WAAW,SAAwB,MAAoD;AAC9F,SAAO,OAAO;AAAA,IACZ,OAAO,QAAQ,QAAQ,MAAM,EAC1B,OAAO,CAAC,CAAC,EAAE,KAAK,MAAM,MAAM,SAAS,IAAI,EACzC,IAAI,CAAC,CAAC,MAAM,KAAK,MAAM,CAAC,MAAM,OAAO,KAAK,MAAM,MAAM,EAAE,MAAM,CAAC;AAAA,EACpE;AACF;AAEA,SAAS,QAAQ,SAAwB,OAA6B;AACpE,QAAM,OAAO,OAAO,KAAK,QAAQ,MAAM,EAAE,KAAK,CAAC,QAAQ,IAAI,YAAY,MAAM,MAAM,YAAY,CAAC;AAEhG,MAAI,SAAS,QAAW;AACtB,WAAO;AAAA,MACL,IAAI;AAAA,MACJ,MAAM,oFAAmB,KAAK;AAAA,IAChC;AAAA,EACF;AAEA,QAAM,QAAQ,QAAQ,OAAO,IAAI;AAEjC,SAAO;AAAA,IACL,IAAI;AAAA,IACJ,SAAS;AAAA,MACP,OAAO;AAAA,MACP,MAAM,MAAM;AAAA,MACZ,SAAS,MAAM;AAAA,MACf,YAAY,OAAO,KAAK,MAAM,MAAM,EAAE;AAAA,MACtC,eAAe,cAAc,IAAI;AAAA,MACjC,QAAQ,OAAO,OAAO,MAAM,MAAM;AAAA,MAClC,UAAU,aAAa,OAAO;AAAA,IAChC;AAAA,EACF;AACF;AAEA,SAAS,YACP,QACA,SACA,WACc;AACd,QAAM,QAAQ,OAAO,WAAW,KAAK,CAAC,MAAM,EAAE,KAAK,YAAY,MAAM,UAAU,YAAY,CAAC;AAE5F,MAAI,CAAC,OAAO;AACV,WAAO;AAAA,MACL,IAAI;AAAA,MACJ,MAAM,2DAAc,SAAS;AAAA,IAC/B;AAAA,EACF;AAEA,MAAI,YAAY,MAAM;AACpB,WAAO;AAAA,MACL,IAAI;AAAA,MACJ,SAAS,EAAE,WAAW,MAAM,MAAM,QAAQ,MAAM,QAAQ,MAAM,YAAY;AAAA,IAC5E;AAAA,EACF;AAIA,QAAM,WAAW,MAAM,OAAO,IAAI,CAAC,SAAS;AAC1C,UAAM,CAAC,OAAO,KAAK,IAAI,KAAK,MAAM,GAAG;AAErC,WAAO,EAAE,MAAM,OAAO,QAAQ,OAAO,KAAK,GAAG,OAAO,KAAK,EAAE;AAAA,EAC7D,CAAC;AACD,QAAM,QAAQ,SACX,IAAI,CAAC,EAAE,MAAM,MAAM,KAAK,EACxB,OAAO,CAAC,UAA+B,UAAU,MAAS;AAC7D,QAAM,UAAU,SAAS,OAAO,CAAC,EAAE,MAAM,MAAM,UAAU,MAAS,EAAE,IAAI,CAAC,EAAE,KAAK,MAAM,IAAI;AAC1F,QAAM,SAAS,CAAC,GAAG,IAAI,IAAI,MAAM,IAAI,CAAC,UAAU,MAAM,KAAK,MAAM,GAAG,EAAE,CAAC,CAAC,CAAC,CAAC;AAE1E,SAAO;AAAA,IACL,IAAI;AAAA,IACJ,SAAS;AAAA,MACP,WAAW,MAAM;AAAA,MACjB;AAAA,MACA,YAAY,MAAM;AAAA,MAClB,eAAe,cAAc,OAAO,CAAC,KAAK,sCAAQ;AAAA,MAClD,QAAQ;AAAA;AAAA;AAAA,MAGR,gBAAgB,eAAe,KAAK;AAAA,MACpC,GAAI,QAAQ,SAAS,EAAE,eAAe,QAAQ,IAAI,CAAC;AAAA,MACnD,UAAU,aAAa,OAAO;AAAA,IAChC;AAAA,EACF;AACF;AAGO,SAAS,oBAAoB,QAAsB,OAAkC;AAC1F,QAAM,UAAU,OAAO;AAEvB,MAAI,MAAM,UAAU,QAAW;AAC7B,WAAO,YAAY,OAAO,EAAE,IAAI,OAAO,MAAM,YAAY,IAAI,QAAQ,SAAS,MAAM,KAAK;AAAA,EAC3F;AAEA,MAAI,MAAM,cAAc,QAAW;AACjC,WAAO,YAAY,QAAQ,SAAS,MAAM,SAAS;AAAA,EACrD;AAEA,MAAI,YAAY,MAAM;AACpB,WAAO;AAAA,MACL,IAAI;AAAA,MACJ,SAAS;AAAA,QACP,MAAM;AAAA,QACN,YAAY,OAAO,WAChB,OAAO,CAAC,MAAM,EAAE,OAAO,SAAS,CAAC,EACjC,IAAI,CAAC,OAAO,EAAE,WAAW,EAAE,MAAM,QAAQ,EAAE,OAAO,EAAE;AAAA,MACzD;AAAA,IACF;AAAA,EACF;AAEA,SAAO;AAAA,IACL,IAAI;AAAA,IACJ,SAAS;AAAA,MACP,gBAAgB,OAAO;AAAA,MACvB,cAAc,QAAQ;AAAA,MACtB,MAAM;AAAA,QACJ,aAAa;AAAA,QACb,QAAQ,WAAW,SAAS,MAAM;AAAA,MACpC;AAAA,MACA,YAAY,EAAE,QAAQ,WAAW,SAAS,WAAW,EAAE;AAAA,MACvD,MAAM;AAAA,IACR;AAAA,EACF;AACF;;;ALtLO,SAAS,cAAc,QAAyB;AACrD,QAAM,SAAS,WAAW;AAC1B,QAAM,QAAQ,UAAU;AACxB,QAAM,qBAAqB,MAAM,KAAK,IAAI,IAAI,MAAM,MAAM,IAAI,CAAC,MAAM,EAAE,IAAI,CAAC,CAAC,EAAE;AAAA,IAC7E,CAAC,GAAG,MAAM,IAAI;AAAA,EAChB;AAEA,SAAO;AAAA,IACL;AAAA,IACA;AAAA,IACA,CAAC;AAAA,IACD,YAAY;AACV,YAAM,OAAO,OAAO,WAAW,IAAI,CAAC,OAAO;AAAA,QACzC,MAAM,EAAE;AAAA,QACR,aAAa,EAAE;AAAA,QACf,UAAU,EAAE;AAAA,QACZ,UAAU,EAAE;AAAA,MACd,EAAE;AAEF,aAAO;AAAA,QACL,SAAS,CAAC,EAAE,MAAM,QAAQ,MAAM,KAAK,UAAU,MAAM,MAAM,CAAC,EAAE,CAAC;AAAA,MACjE;AAAA,IACF;AAAA,EACF;AAEA,SAAO;AAAA,IACL;AAAA,IACA;AAAA,IACA;AAAA,MACE,MAAM,EAAE,OAAO,EAAE,SAAS,4IAAmC;AAAA,MAC7D,SAAS,EACN,OAAO,EACP,SAAS,EACT,SAAS,0UAA2E;AAAA,MACvF,SAAS,EACN,OAAO,EACP,SAAS,EACT,SAAS,+RAAkE;AAAA,MAC9E,MAAM,EAAE,QAAQ,EAAE,SAAS,EAAE,SAAS,6JAAqC;AAAA,MAC3E,QAAQ,EACL,OAAO,EACP,IAAI,EACJ,YAAY,EACZ,SAAS,EACT,SAAS,kWAAqE;AAAA,IACnF;AAAA,IACA,OAAO,EAAE,MAAM,SAAS,SAAS,MAAM,OAAO,MAAM;AAClD,YAAM,YAAY,OAAO,WAAW,KAAK,CAAC,MAAM,EAAE,KAAK,YAAY,MAAM,KAAK,YAAY,CAAC;AAE3F,UAAI,CAAC,WAAW;AACd,eAAO;AAAA,UACL,SAAS;AAAA,YACP;AAAA,cACE,MAAM;AAAA,cACN,MAAM,2DAAc,IAAI;AAAA,YAC1B;AAAA,UACF;AAAA,UACA,SAAS;AAAA,QACX;AAAA,MACF;AAEA,YAAM,SAAS,uBAAuB,WAAW,EAAE,SAAS,SAAS,MAAM,OAAO,CAAC;AAEnF,aAAO,OAAO,KACV,EAAE,SAAS,CAAC,EAAE,MAAM,QAAQ,MAAM,OAAO,KAAK,CAAC,EAAE,IACjD,EAAE,SAAS,CAAC,EAAE,MAAM,QAAQ,MAAM,OAAO,KAAK,CAAC,GAAG,SAAS,KAAK;AAAA,IACtE;AAAA,EACF;AAEA,SAAO;AAAA,IACL;AAAA,IACA;AAAA,IACA;AAAA,MACE,WAAW,EACR,OAAO,EACP,SAAS,EACT,SAAS,+TAA0E;AAAA,MACtF,OAAO,EACJ,OAAO,EACP,SAAS,EACT,SAAS,4RAAqE;AAAA,IACnF;AAAA,IACA,OAAO,EAAE,WAAW,MAAM,MAAM;AAC9B,YAAM,SAAS,oBAAoB,QAAQ,EAAE,WAAW,MAAM,CAAC;AAE/D,aAAO,OAAO,KACV,EAAE,SAAS,CAAC,EAAE,MAAM,QAAQ,MAAM,KAAK,UAAU,OAAO,SAAS,MAAM,CAAC,EAAE,CAAC,EAAE,IAC7E,EAAE,SAAS,CAAC,EAAE,MAAM,QAAQ,MAAM,OAAO,KAAK,CAAC,GAAG,SAAS,KAAK;AAAA,IACtE;AAAA,EACF;AAEA,SAAO;AAAA,IACL;AAAA,IACA;AAAA,IACA,CAAC;AAAA,IACD,YAAY;AACV,YAAM,SAAS,wBAAwB,MAAM;AAE7C,aAAO,OAAO,KACV,EAAE,SAAS,CAAC,EAAE,MAAM,QAAQ,MAAM,OAAO,KAAK,CAAC,EAAE,IACjD,EAAE,SAAS,CAAC,EAAE,MAAM,QAAQ,MAAM,OAAO,KAAK,CAAC,GAAG,SAAS,KAAK;AAAA,IACtE;AAAA,EACF;AAEA,SAAO;AAAA,IACL;AAAA,IACA;AAAA,IACA;AAAA,MACE,SAAS,EAAE,OAAO,EAAE,KAAK,EAAE,IAAI,CAAC,EAAE,SAAS,EAAE,SAAS,0GAAoC;AAAA,IAC5F;AAAA,IACA,OAAO,EAAE,QAAQ,MAAM;AACrB,YAAM,gBAAgB,WAAW,OAAO;AACxC,YAAM,OAAO,OAAO,aAAa,KAAK,CAAC,MAAM,EAAE,YAAY,aAAa;AAExE,UAAI,MAAM;AACR,eAAO,EAAE,SAAS,CAAC,EAAE,MAAM,QAAQ,MAAM,KAAK,IAAI,CAAC,EAAE;AAAA,MACvD;AAEA,YAAM,oBAAoB,OAAO,aAC9B,IAAI,CAAC,MAAM,EAAE,OAAO,EACpB,KAAK,CAAC,GAAG,MAAM,EAAE,cAAc,GAAG,MAAM,EAAE,SAAS,KAAK,CAAC,CAAC,EAC1D,MAAM,GAAG,CAAC;AACb,YAAM,OAAO,kBAAkB,SAC3B,6JAAgC,kBAAkB,KAAK,IAAI,CAAC,MAC5D;AAEJ,aAAO;AAAA,QACL,SAAS;AAAA,UACP;AAAA,YACE,MAAM;AAAA,YACN,MAAM,4CAA6B,aAAa,sFAA0B,IAAI;AAAA,UAChF;AAAA,QACF;AAAA,QACA,SAAS;AAAA,MACX;AAAA,IACF;AAAA,EACF;AAEA,SAAO;AAAA,IACL;AAAA,IACA;AAAA,IACA;AAAA,MACE,OAAO,EACJ,OAAO,EACP,SAAS,EACT;AAAA,QACC;AAAA,MACF;AAAA,MACF,MAAM,EACH,OAAO,EACP,IAAI,EACJ,SAAS,EACT,SAAS,EACT,SAAS,4RAA0E;AAAA,MACtF,OAAO,EACJ,OAAO,EACP,IAAI,EACJ,SAAS,EACT,IAAI,GAAG,EACP,SAAS,EACT,SAAS,6MAA6C;AAAA,IAC3D;AAAA,IACA,OAAO,EAAE,OAAO,MAAM,MAAM,MAAM;AAChC,UAAI,MAAM,MAAM,WAAW,GAAG;AAC5B,eAAO;AAAA,UACL,SAAS;AAAA,YACP;AAAA,cACE,MAAM;AAAA,cACN,MAAM;AAAA,YACR;AAAA,UACF;AAAA,UACA,SAAS;AAAA,QACX;AAAA,MACF;AAEA,YAAM,SAAS,OAAO,KAAK,EAAE,YAAY,KAAK;AAC9C,YAAM,MAAM,SAAS;AAErB,YAAM,UAAU,MAAM,MAAM,OAAO,CAAC,OAAO;AACzC,YAAI,SAAS,UAAa,GAAG,SAAS,KAAM,QAAO;AACnD,YAAI,UAAU,CAAC,GAAG,KAAK,YAAY,EAAE,SAAS,MAAM,EAAG,QAAO;AAC9D,eAAO;AAAA,MACT,CAAC;AAED,YAAM,YAAY,QAAQ,SAAS;AACnC,YAAM,OAAO,YAAY,QAAQ,MAAM,GAAG,GAAG,IAAI;AAEjD,YAAM,UAAU;AAAA,QACd,SAAS,GAAG,MAAM,WAAW,IAAI,MAAM,cAAc;AAAA,QACrD,eAAe,MAAM,MAAM;AAAA,QAC3B,SAAS,QAAQ;AAAA,QACjB,UAAU,KAAK;AAAA,QACf;AAAA,QACA,gBAAgB;AAAA,QAChB,OAAO;AAAA,QACP,OAAO;AAAA,MACT;AAEA,aAAO;AAAA,QACL,SAAS,CAAC,EAAE,MAAM,QAAQ,MAAM,KAAK,UAAU,SAAS,MAAM,CAAC,EAAE,CAAC;AAAA,MACpE;AAAA,IACF;AAAA,EACF;AACF;;;AD/MO,SAAS,eAA0B;AACxC,QAAM,SAAS,IAAI,UAAU;AAAA,IAC3B,MAAM;AAAA,IACN,SAAS;AAAA,EACX,CAAC;AAED,gBAAc,MAAM;AAEpB,SAAO;AACT;;;ADRA,IAAM,wBAAN,cAAoC,qBAAqB;AAAA,EACvD,MAAe,QAAuB;AACpC,UAAM,gBAAgB,KAAK;AAC3B,SAAK,YAAY,CAAC,YAAY;AAG5B,UACE,iBAAiB,OAAO,KACxB,QAAQ,WAAW,gBACnB,QAAQ,QAAQ,SAAS,uBACzB,QAAQ,OAAO,cAAc,QAC7B;AACA,gBAAQ,OAAO,YAAY,CAAC;AAAA,MAC9B;AACA,sBAAgB,OAAO;AAAA,IACzB;AACA,UAAM,MAAM,MAAM;AAAA,EACpB;AACF;AAEA,eAAe,OAAO;AACpB,QAAM,SAAS,aAAa;AAC5B,QAAM,YAAY,IAAI,sBAAsB;AAC5C,QAAM,OAAO,QAAQ,SAAS;AAC9B,UAAQ,MAAM,4BAA4B;AAC5C;AAEA,KAAK,EAAE,MAAM,CAAC,UAAU;AACtB,UAAQ,MAAM,2BAA2B,KAAK;AAC9C,UAAQ,KAAK,CAAC;AAChB,CAAC;","names":[]}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@sberbusiness/triplex-next-mcp-server",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.53.1",
|
|
4
4
|
"description": "MCP-сервер для дизайн-системы Triplex. Предоставляет AI-агентам документацию компонентов, дизайн-токены и примеры использования.",
|
|
5
5
|
"author": "СберБизнес",
|
|
6
6
|
"license": "MIT",
|