iwgt 2.3.0

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/dist/server.js ADDED
@@ -0,0 +1,579 @@
1
+ import { Server } from '@modelcontextprotocol/sdk/server/index.js';
2
+ import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js';
3
+ import { CallToolRequestSchema, ListToolsRequestSchema, ListResourcesRequestSchema, ReadResourceRequestSchema, } from '@modelcontextprotocol/sdk/types.js';
4
+ import { readFileSync } from 'fs';
5
+ import { fileURLToPath } from 'url';
6
+ import { dirname, join } from 'path';
7
+ const __filename = fileURLToPath(import.meta.url);
8
+ const __dirname = dirname(__filename);
9
+ // Импорт справочников
10
+ import categorySettings from './data/references/category-settings.json' with { type: 'json' };
11
+ import blockTemplatesFull from './data/references/block-templates-full.json' with { type: 'json' };
12
+ import librariesRegistry from './data/references/libraries-registry.json' with { type: 'json' };
13
+ import iconsRegistry from './data/references/icons-registry.json' with { type: 'json' };
14
+ import myLayoutReference from './data/references/my-layout-reference.json' with { type: 'json' };
15
+ import liquidVariables from './data/references/liquid-variables.json' with { type: 'json' };
16
+ import liquidFilters from './data/references/liquid-filters.json' with { type: 'json' };
17
+ import commonjsReference from './data/references/commonjs-reference.json' with { type: 'json' };
18
+ import collectionsMenuPatterns from './data/references/collections-menu-patterns.json' with { type: 'json' };
19
+ // Импорт модулей
20
+ import { generateWidgetFiles } from './generators/index.js';
21
+ import * as tools from './tools/index.js';
22
+ import * as utils from './utils/index.js';
23
+ export class WidgetServer {
24
+ server;
25
+ constructor() {
26
+ this.server = new Server({
27
+ name: 'insales-widgets',
28
+ version: '2.0.0',
29
+ }, {
30
+ capabilities: {
31
+ tools: {},
32
+ resources: {},
33
+ },
34
+ });
35
+ this.setupHandlers();
36
+ }
37
+ setupHandlers() {
38
+ // Список инструментов
39
+ this.server.setRequestHandler(ListToolsRequestSchema, async () => ({
40
+ tools: [
41
+ {
42
+ name: 'create_widget',
43
+ description: `Создает полный виджет InSales по описанию. Генерирует содержимое всех необходимых файлов: info.json, settings_form.json, settings_data.json, snippet.liquid, snippet.scss, snippet.js, messages.json, setup.json (для block_list_widget_type).
44
+
45
+ КРИТИЧЕСКИ ВАЖНО перед использованием:
46
+ 1. Прочитать ресурс 'insales://widget-architecture' для понимания системной обёртки виджетов
47
+ 2. Помнить: НЕ используется Vue.js, кастомные теги типа ui-grid-cell - это ОШИБКА
48
+ 3. Для блочных виджетов блоки доступны через data.blocks в Liquid
49
+ 4. Код из snippet.liquid автоматически оборачивается в div.layout с CSS-переменными из настроек
50
+ 5. ⚠️ SCSS: Первая строка snippet.scss ВСЕГДА должна быть @include background-color(--bg); - это устанавливает фон И автоматически определяет контрастный цвет текста
51
+ 6. ⚠️ ИКОНКИ: Фильтра | icon НЕ СУЩЕСТВУЕТ! Используйте: <i class="icon icon-название"></i>
52
+ 7. Для иконок используется иконочный шрифт (76 иконок) - используйте инструмент get_available_icons
53
+ 8. В snippet.js помнить про цикл по виджетам ($widget.each) - на странице может быть несколько экземпляров
54
+
55
+ КАТЕГОРИИ ВИДЖЕТОВ (используйте точные названия):
56
+ - headers (шапка сайта), footers (подвал), cart (корзина)
57
+ - sliders (слайдеры), banner (баннеры), benefits (преимущества)
58
+ - products-cards (карточки товаров), collection-products (товары категории)
59
+ - navigation (навигация), forms (формы), text (текстовые блоки)
60
+ - и другие - используйте get_category_info для получения полного списка`,
61
+ inputSchema: {
62
+ type: 'object',
63
+ properties: {
64
+ description: {
65
+ type: 'string',
66
+ description: 'Описание виджета (например: "Промо слайдер с автопрокруткой")',
67
+ },
68
+ category: {
69
+ type: 'string',
70
+ description: 'Категория виджета (headers, footers, sliders, banner, cart и т.д.). ВАЖНО: для шапки используйте "headers" (множественное число). Опционально - определится автоматически.',
71
+ },
72
+ type: {
73
+ type: 'string',
74
+ enum: ['simple_widget_type', 'block_list_widget_type'],
75
+ description: 'Тип виджета. simple_widget_type - простой виджет, block_list_widget_type - виджет со списком блоков',
76
+ },
77
+ handle: {
78
+ type: 'string',
79
+ description: 'Handle виджета (например: my_promo_slider). Опционально - сгенерируется автоматически',
80
+ },
81
+ },
82
+ required: ['description'],
83
+ },
84
+ },
85
+ {
86
+ name: 'get_block_templates',
87
+ description: 'Получить список доступных шаблонов блоков с фильтрацией',
88
+ inputSchema: {
89
+ type: 'object',
90
+ properties: {
91
+ category: {
92
+ type: 'string',
93
+ description: 'Категория для фильтрации шаблонов',
94
+ },
95
+ search: {
96
+ type: 'string',
97
+ description: 'Поисковый запрос по keywords',
98
+ },
99
+ },
100
+ },
101
+ },
102
+ {
103
+ name: 'get_available_icons',
104
+ description: 'Получить список доступных иконок (76 шт) с возможностью поиска. Иконки используются через иконочный шрифт. В Liquid и HTML: <i class="icon icon-cart"></i>. Класс формата: icon icon-название',
105
+ inputSchema: {
106
+ type: 'object',
107
+ properties: {
108
+ search: {
109
+ type: 'string',
110
+ description: 'Поиск иконки по ключевым словам',
111
+ },
112
+ category: {
113
+ type: 'string',
114
+ enum: ['navigation', 'actions', 'commerce', 'communication', 'interface'],
115
+ description: 'Категория иконок',
116
+ },
117
+ },
118
+ },
119
+ },
120
+ {
121
+ name: 'get_category_info',
122
+ description: 'Получить информацию о категории виджетов: типичные настройки, библиотеки, примеры',
123
+ inputSchema: {
124
+ type: 'object',
125
+ properties: {
126
+ category: {
127
+ type: 'string',
128
+ description: 'Handle категории',
129
+ },
130
+ },
131
+ required: ['category'],
132
+ },
133
+ },
134
+ {
135
+ name: 'get_libraries_info',
136
+ description: 'Получить информацию о доступных библиотеках',
137
+ inputSchema: {
138
+ type: 'object',
139
+ properties: {
140
+ category: {
141
+ type: 'string',
142
+ description: 'Фильтр по категории виджетов',
143
+ },
144
+ },
145
+ },
146
+ },
147
+ {
148
+ name: 'get_liquid_variables',
149
+ description: 'Получить справочник Liquid переменных InSales (436 переменных в 19 категориях)',
150
+ inputSchema: {
151
+ type: 'object',
152
+ properties: {
153
+ category: {
154
+ type: 'string',
155
+ description: 'Категория переменных (Product, Collection, Cart, Blog, и т.д.)',
156
+ },
157
+ search: {
158
+ type: 'string',
159
+ description: 'Поиск переменных по названию или описанию',
160
+ },
161
+ },
162
+ },
163
+ },
164
+ {
165
+ name: 'get_liquid_filters',
166
+ description: 'Получить справочник Liquid фильтров InSales (53 фильтра в 7 категориях)',
167
+ inputSchema: {
168
+ type: 'object',
169
+ properties: {
170
+ category: {
171
+ type: 'string',
172
+ description: 'Категория фильтров (массивы, математические, строковые, изображения, и т.д.)',
173
+ },
174
+ search: {
175
+ type: 'string',
176
+ description: 'Поиск фильтров по названию или описанию',
177
+ },
178
+ },
179
+ },
180
+ },
181
+ {
182
+ name: 'get_commonjs_api',
183
+ description: 'Получить справочник CommonJS API для работы с магазином InSales (10 модулей, 43 метода, 24+ события). Включает декларативные data-атрибуты для работы без JavaScript.',
184
+ inputSchema: {
185
+ type: 'object',
186
+ properties: {
187
+ category: {
188
+ type: 'string',
189
+ description: 'Категория API (product, cart, lists, search, forms, events, helpers, checkout)',
190
+ },
191
+ module: {
192
+ type: 'string',
193
+ description: 'Модуль API (Products, Cart, EventBus, ajaxAPI, Compare, FavoritesProducts, Shop, Template, AjaxSearch)',
194
+ },
195
+ search: {
196
+ type: 'string',
197
+ description: 'Поиск методов, атрибутов, событий по названию или описанию. Поиск включает события методов (например, add_items:insales:cart при Cart.add)',
198
+ },
199
+ },
200
+ },
201
+ },
202
+ {
203
+ name: 'get_collections_menu',
204
+ description: 'Получить паттерны меню категорий для виджетов InSales. Возвращает готовые решения для создания меню категорий с кешированием, различными структурами и функциональностью. Доступные паттерны: two_level_hierarchical (двухуровневое меню), multi_level_flatten (многоуровневое через flatten_branch), simple_subcollections (простое меню подкатегорий), flat_collections_list (плоский список), tree_structure_flatten (древовидная структура).',
205
+ inputSchema: {
206
+ type: 'object',
207
+ properties: {
208
+ patternId: {
209
+ type: 'string',
210
+ description: 'ID паттерна меню (two_level_hierarchical, multi_level_flatten, simple_subcollections, flat_collections_list, tree_structure_flatten). Укажите для получения полного кода паттерна с настройками.',
211
+ },
212
+ category: {
213
+ type: 'string',
214
+ description: 'Фильтр по категории/назначению (шапка, сайдбар, категория и т.д.)',
215
+ },
216
+ },
217
+ },
218
+ },
219
+ ],
220
+ }));
221
+ // Список ресурсов
222
+ this.server.setRequestHandler(ListResourcesRequestSchema, async () => ({
223
+ resources: [
224
+ {
225
+ uri: 'insales://category-settings',
226
+ name: 'Настройки категорий виджетов',
227
+ mimeType: 'application/json',
228
+ description: 'Справочник настроек для каждой категории виджетов',
229
+ },
230
+ {
231
+ uri: 'insales://block-templates',
232
+ name: 'Шаблоны блоков',
233
+ mimeType: 'application/json',
234
+ description: 'Полный справочник доступных шаблонов блоков',
235
+ },
236
+ {
237
+ uri: 'insales://libraries',
238
+ name: 'Библиотеки',
239
+ mimeType: 'application/json',
240
+ description: 'Справочник доступных библиотек и плагинов',
241
+ },
242
+ {
243
+ uri: 'insales://icons',
244
+ name: 'Иконки',
245
+ mimeType: 'application/json',
246
+ description: 'Справочник доступных иконок (76 шт). Используются через иконочный шрифт: <i class="icon icon-название"></i>',
247
+ },
248
+ {
249
+ uri: 'insales://my-layout',
250
+ name: 'My-Layout компоненты',
251
+ mimeType: 'application/json',
252
+ description: 'Справочник компонентов библиотеки my-layout',
253
+ },
254
+ {
255
+ uri: 'insales://liquid-variables',
256
+ name: 'Liquid переменные',
257
+ mimeType: 'application/json',
258
+ description: 'Справочник Liquid переменных InSales (436 переменных)',
259
+ },
260
+ {
261
+ uri: 'insales://liquid-filters',
262
+ name: 'Liquid фильтры',
263
+ mimeType: 'application/json',
264
+ description: 'Справочник Liquid фильтров InSales (53 фильтра)',
265
+ },
266
+ {
267
+ uri: 'insales://commonjs-api',
268
+ name: 'CommonJS API',
269
+ mimeType: 'application/json',
270
+ description: 'Справочник CommonJS API InSales',
271
+ },
272
+ {
273
+ uri: 'insales://collections-menu-patterns',
274
+ name: 'Паттерны меню категорий',
275
+ mimeType: 'application/json',
276
+ description: 'Справочник паттернов для создания меню категорий: двухуровневое, многоуровневое, простое, плоское, древовидное',
277
+ },
278
+ {
279
+ uri: 'insales://widget-architecture',
280
+ name: 'Архитектура и контекст виджетов',
281
+ mimeType: 'text/markdown',
282
+ description: 'КРИТИЧЕСКИ ВАЖНО: Системная обёртка виджетов, контекст выполнения, data.blocks, запрещённые практики',
283
+ },
284
+ ],
285
+ }));
286
+ // Чтение ресурсов
287
+ this.server.setRequestHandler(ReadResourceRequestSchema, async (request) => {
288
+ const uri = request.params.uri;
289
+ switch (uri) {
290
+ case 'insales://category-settings':
291
+ return {
292
+ contents: [
293
+ {
294
+ uri,
295
+ mimeType: 'application/json',
296
+ text: JSON.stringify(categorySettings, null, 2),
297
+ },
298
+ ],
299
+ };
300
+ case 'insales://block-templates':
301
+ return {
302
+ contents: [
303
+ {
304
+ uri,
305
+ mimeType: 'application/json',
306
+ text: JSON.stringify(blockTemplatesFull, null, 2),
307
+ },
308
+ ],
309
+ };
310
+ case 'insales://libraries':
311
+ return {
312
+ contents: [
313
+ {
314
+ uri,
315
+ mimeType: 'application/json',
316
+ text: JSON.stringify(librariesRegistry, null, 2),
317
+ },
318
+ ],
319
+ };
320
+ case 'insales://icons':
321
+ return {
322
+ contents: [
323
+ {
324
+ uri,
325
+ mimeType: 'application/json',
326
+ text: JSON.stringify(iconsRegistry, null, 2),
327
+ },
328
+ ],
329
+ };
330
+ case 'insales://my-layout':
331
+ return {
332
+ contents: [
333
+ {
334
+ uri,
335
+ mimeType: 'application/json',
336
+ text: JSON.stringify(myLayoutReference, null, 2),
337
+ },
338
+ ],
339
+ };
340
+ case 'insales://liquid-variables':
341
+ return {
342
+ contents: [
343
+ {
344
+ uri,
345
+ mimeType: 'application/json',
346
+ text: JSON.stringify(liquidVariables, null, 2),
347
+ },
348
+ ],
349
+ };
350
+ case 'insales://liquid-filters':
351
+ return {
352
+ contents: [
353
+ {
354
+ uri,
355
+ mimeType: 'application/json',
356
+ text: JSON.stringify(liquidFilters, null, 2),
357
+ },
358
+ ],
359
+ };
360
+ case 'insales://commonjs-api':
361
+ return {
362
+ contents: [
363
+ {
364
+ uri,
365
+ mimeType: 'application/json',
366
+ text: JSON.stringify(commonjsReference, null, 2),
367
+ },
368
+ ],
369
+ };
370
+ case 'insales://collections-menu-patterns':
371
+ return {
372
+ contents: [
373
+ {
374
+ uri,
375
+ mimeType: 'application/json',
376
+ text: JSON.stringify(collectionsMenuPatterns, null, 2),
377
+ },
378
+ ],
379
+ };
380
+ case 'insales://widget-architecture': {
381
+ // Читаем markdown файл с документацией об архитектуре
382
+ const docPath = join(__dirname, '../context-content/doc/4 поколение/Виджеты/widget-wrapper-and-context.md');
383
+ const content = readFileSync(docPath, 'utf-8');
384
+ return {
385
+ contents: [
386
+ {
387
+ uri,
388
+ mimeType: 'text/markdown',
389
+ text: content,
390
+ },
391
+ ],
392
+ };
393
+ }
394
+ default:
395
+ throw new Error(`Unknown resource: ${uri}`);
396
+ }
397
+ });
398
+ // Обработка вызовов инструментов
399
+ this.server.setRequestHandler(CallToolRequestSchema, async (request) => {
400
+ const { name, arguments: args } = request.params;
401
+ try {
402
+ switch (name) {
403
+ case 'create_widget':
404
+ return await this.createWidget(args || {});
405
+ case 'get_block_templates':
406
+ return {
407
+ content: [
408
+ {
409
+ type: 'text',
410
+ text: JSON.stringify(tools.getBlockTemplates(args || {}), null, 2),
411
+ },
412
+ ],
413
+ };
414
+ case 'get_available_icons':
415
+ return {
416
+ content: [
417
+ {
418
+ type: 'text',
419
+ text: JSON.stringify(tools.getAvailableIcons(args || {}), null, 2),
420
+ },
421
+ ],
422
+ };
423
+ case 'get_category_info':
424
+ return {
425
+ content: [
426
+ {
427
+ type: 'text',
428
+ text: JSON.stringify(tools.getCategoryInfo(args || {}), null, 2),
429
+ },
430
+ ],
431
+ };
432
+ case 'get_libraries_info':
433
+ return {
434
+ content: [
435
+ {
436
+ type: 'text',
437
+ text: JSON.stringify(tools.getLibrariesInfo(args || {}), null, 2),
438
+ },
439
+ ],
440
+ };
441
+ case 'get_liquid_variables':
442
+ return {
443
+ content: [
444
+ {
445
+ type: 'text',
446
+ text: JSON.stringify(tools.getLiquidVariables(args || {}), null, 2),
447
+ },
448
+ ],
449
+ };
450
+ case 'get_liquid_filters':
451
+ return {
452
+ content: [
453
+ {
454
+ type: 'text',
455
+ text: JSON.stringify(tools.getLiquidFilters(args || {}), null, 2),
456
+ },
457
+ ],
458
+ };
459
+ case 'get_commonjs_api':
460
+ return {
461
+ content: [
462
+ {
463
+ type: 'text',
464
+ text: JSON.stringify(tools.getCommonJSAPI(args || {}), null, 2),
465
+ },
466
+ ],
467
+ };
468
+ case 'get_collections_menu':
469
+ return {
470
+ content: [
471
+ {
472
+ type: 'text',
473
+ text: JSON.stringify(tools.getCollectionsMenuPatterns(args || {}), null, 2),
474
+ },
475
+ ],
476
+ };
477
+ default:
478
+ throw new Error(`Unknown tool: ${name}`);
479
+ }
480
+ }
481
+ catch (error) {
482
+ const errorMessage = error instanceof Error ? error.message : String(error);
483
+ return {
484
+ content: [
485
+ {
486
+ type: 'text',
487
+ text: `Error: ${errorMessage}`,
488
+ },
489
+ ],
490
+ isError: true,
491
+ };
492
+ }
493
+ });
494
+ }
495
+ // Создание виджета
496
+ async createWidget(params) {
497
+ const description = params.description;
498
+ const category = params.category || utils.inferCategory(description);
499
+ const categoryData = categorySettings[category];
500
+ if (!categoryData) {
501
+ throw new Error(`Неизвестная категория: ${category}`);
502
+ }
503
+ // Генерируем или валидируем handle
504
+ let handle = params.handle || utils.generateHandle(description);
505
+ if (params.handle) {
506
+ const validation = utils.validateHandle(params.handle);
507
+ if (!validation.valid) {
508
+ throw new Error(validation.error);
509
+ }
510
+ }
511
+ const type = params.type || utils.inferType(description);
512
+ // Выбор блок-темплейта
513
+ let blockTemplate;
514
+ if (type === 'block_list_widget_type') {
515
+ blockTemplate = utils.selectBlockTemplate(description, category);
516
+ }
517
+ // Конфигурация виджета
518
+ const config = {
519
+ handle,
520
+ category,
521
+ type,
522
+ description,
523
+ blockTemplate,
524
+ libraries: categoryData.libraries,
525
+ commonSettings: categoryData.commonSettings.filter(s => (s.frequency || 0) > 0.5),
526
+ };
527
+ // Генерация содержимого файлов
528
+ const files = generateWidgetFiles(config);
529
+ // Форматируем вывод для AI-агента
530
+ let output = `✅ Виджет создан успешно!\n\n`;
531
+ output += `📦 Handle: ${handle}\n`;
532
+ output += `📂 Категория: ${category}\n`;
533
+ output += `🔧 Тип: ${type}\n`;
534
+ output += `📚 Библиотеки: ${categoryData.libraries.join(', ')}\n`;
535
+ output += `⚙️ Настроек: ${files.settings_form.settingsCount}\n`;
536
+ if (blockTemplate) {
537
+ output += `🎨 Блок-темплейт: ${blockTemplate.handle}\n`;
538
+ }
539
+ output += `\n`;
540
+ output += `📄 Созданные файлы:\n`;
541
+ output += Object.keys(files).filter(k => k !== 'settings_form').map(name => ` - ${name}`).join('\n');
542
+ output += `\n\n`;
543
+ output += `📝 СОДЕРЖИМОЕ ФАЙЛОВ:\n`;
544
+ output += `${'='.repeat(80)}\n\n`;
545
+ // Добавляем содержимое каждого файла
546
+ for (const [filename, content] of Object.entries(files)) {
547
+ if (filename === 'settings_form') {
548
+ // settings_form содержит только метаинформацию, пропускаем
549
+ continue;
550
+ }
551
+ output += `\n${'─'.repeat(80)}\n`;
552
+ output += `📄 ${filename}\n`;
553
+ output += `${'─'.repeat(80)}\n`;
554
+ output += typeof content === 'string' ? content : JSON.stringify(content, null, 2);
555
+ output += `\n`;
556
+ }
557
+ output += `\n${'='.repeat(80)}\n`;
558
+ output += `\n✨ Все файлы готовы к использованию!\n`;
559
+ output += `\n💡 Следующие шаги:\n`;
560
+ output += `1. Создайте директорию для виджета: ${handle}\n`;
561
+ output += `2. Сохраните каждый файл с соответствующим именем в эту директорию\n`;
562
+ output += `3. Настройте стили в snippet.scss под свои нужды\n`;
563
+ output += `4. Добавьте JavaScript функциональность в snippet.js\n`;
564
+ return {
565
+ content: [
566
+ {
567
+ type: 'text',
568
+ text: output,
569
+ },
570
+ ],
571
+ };
572
+ }
573
+ async run() {
574
+ const transport = new StdioServerTransport();
575
+ await this.server.connect(transport);
576
+ console.error('InSales Widgets MCP Server running on stdio');
577
+ }
578
+ }
579
+ //# sourceMappingURL=server.js.map
@@ -0,0 +1,38 @@
1
+ /**
2
+ * Инструменты для работы со справочной информацией
3
+ * Модуль содержит функции для получения данных из справочников
4
+ */
5
+ /**
6
+ * Получить список блок-темплейтов с фильтрацией
7
+ */
8
+ export declare function getBlockTemplates(args?: any): any;
9
+ /**
10
+ * Получить список доступных иконок
11
+ * Иконки используются через иконочный шрифт
12
+ */
13
+ export declare function getAvailableIcons(args?: any): any;
14
+ /**
15
+ * Получить информацию о категории виджетов
16
+ */
17
+ export declare function getCategoryInfo(args: any): any;
18
+ /**
19
+ * Получить информацию о библиотеках
20
+ */
21
+ export declare function getLibrariesInfo(args?: any): any;
22
+ /**
23
+ * Получить справочник Liquid переменных
24
+ */
25
+ export declare function getLiquidVariables(args?: any): any;
26
+ /**
27
+ * Получить справочник Liquid фильтров
28
+ */
29
+ export declare function getLiquidFilters(args?: any): any;
30
+ /**
31
+ * Получить справочник CommonJS API
32
+ */
33
+ export declare function getCommonJSAPI(args?: any): any;
34
+ /**
35
+ * Получить паттерны меню категорий
36
+ */
37
+ export declare function getCollectionsMenuPatterns(args?: any): any;
38
+ //# sourceMappingURL=index.d.ts.map